Я достаточно гуглил, но не смог понять, что означает скобка ()
. Кроме того, я вижу некоторый синтаксис как movl 8(%ebp), %eax
Может кто-нибудь предложить мне хорошую ссылку? Я не смог найти ни одного из 20 лучших результатов от Google.
Я достаточно гуглил, но не смог понять, что означает скобка ()
. Кроме того, я вижу некоторый синтаксис как movl 8(%ebp), %eax
Может кто-нибудь предложить мне хорошую ссылку? Я не смог найти ни одного из 20 лучших результатов от Google.
%eax
- регистр EAX; (%eax)
- это ячейка памяти, адрес которой содержится в регистре EAX; 8(%eax)
- это ячейка памяти, адрес которой является значением EAX плюс 8.
http://web.archive.org/web/20080215230650/http://sig9.com/articles/att-syntax - это краткое введение в синтаксис asm Unix (AT & T). Погуглил по at&t asm syntax
.
Сообщение "Синтаксис сборки AT & T", автор vivek (http://web.archive.org/web/20080228052132/http://sig9.com/blog/vivek), 2003-09-01. Из него можно получить основную информацию об AT & T:
Например, общий формат базовой команды перемещения данных в INTEL-синтаксисе:
mnemonic destination, source
в то время как в случае AT & T общий формат
mnemonic source, destination
(Я помню этот порядок, когда AT & T asm назывался подлинным Unix Asm, поэтому он правильный и передает данные вправо; в то время как синтаксис 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 это делается путем добавления ключевого слова castte 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
Он также рекомендует gnu в качестве (газа) документов: http://web.archive.org/web/20080313132324/http://sourceware.org/binutils/docs-2.16/as/index.html.
Они перемещают инструкции, перемещая данные из одного места в другое - в этих случаях из памяти в регистр:
register_eax = *(unsigned long *)register_eax;
Другой пример:
register_eax = *(unsigned long *)(register_ebp + 8);