(Я помню этот порядок, когда AT & T asm назывался подлинным Unix asm, поэтому он right one и передает данные вправо; в то время как синтаксис Intel основывался на некотором неверном документе masms, которыйявно не подходят для мира Unix, они слева и потоки данных слева)
Все имена регистров архитектуры IA-32 должны начинаться с префикса "%"знак, например,% al,% bx,% ds,% cr0 и т. д.
Все литеральные значения должны начинаться с префикса '$'. Например,
mov $100, %bx
mov $A, %al
Первыйинструкция перемещает значение 100 в регистр AX, а вторая перемещает числовое значение ascii A в регистр AL.
В синтаксисе AT & T к памяти обращаются следующим образом,
segment-override:signed-offset(base,index,scale)
части которых могут быть опущены в зависимости от желаемого адреса.>% Es: 100 (% eax,%ebx, 2)
Обратите внимание, что смещения и масштаб не должны начинаться с префикса «$».Еще несколько примеров с их эквивалентным NASM-синтаксисом должны прояснить ситуацию:
GAS memory operand NASM memory operand
------------------ -------------------
100 [100]
%es:100 [es:100]
(%eax) [eax]
(%eax,%ebx) [eax+ebx]
(%ecx,%ebx,2) [ecx+ebx*2]
(,%ebx,2) [ebx*2]
-10(%eax) [eax-10]
%ds:-10(%ebp) [ds:ebp-10]
Example instructions,
mov %ax, 100
mov %eax, -100(%eax)
Размеры операндов.Иногда, особенно при перемещении литеральных значений в память, становится необходимым указывать размер передачи или размер операнда.Например, инструкция
mov $10, 100
только указывает, что значение 10 должно быть перемещено в смещение 100 памяти, но не размер передачи.В NASM это делается путем добавления ключевого слова casting byte / word / dword и т. Д. К любому из операндов.В синтаксисе AT & T это делается путем добавления суффикса - b / w / l - к инструкции.Например,
movb $10, %es:(%eax)
перемещает байтовое значение 10 в область памяти [ea: eax], тогда как
movl $10, %es:(%eax)
перемещает длинное значение (dword) 10 в то же место.
Инструкции jmp, call, ret и т. Д. Переносят управление из одной части программы в другую.Их можно классифицировать как передачу управления одному и тому же сегменту кода (рядом) или различным сегментам кода (далеко).Возможные типы адресации ветвей: относительное смещение (метка), регистр, операнд памяти и указатели смещения сегмента.
Относительные смещения задаются с помощью меток, как показано ниже.
label1:
.
.
jmp label1
Адресация ветвей с использованием регистров или операндов памяти должна начинаться с префикса '*'.Чтобы указать «дальние» контрольные передачи, необходимо добавить префикс «l», например, «ljmp», «lcall» и т. Д. Например,
GAS syntax NASM syntax
========== ===========
jmp *100 jmp near [100]
call *100 call near [100]
jmp *%eax jmp near eax
jmp *%ecx call near ecx
jmp *(%eax) jmp near [eax]
call *(%ebx) call near [ebx]
ljmp *100 jmp far [100]
lcall *100 call far [100]
ljmp *(%eax) jmp far [eax]
lcall *(%ebx) call far [ebx]
ret retn
lret retf
lret $0x100 retf 0x100
Указатели со смещением сегмента указываются с использованием следующегоформат:
jmp $segment, $offset