Что означает скобка в "movl (% eax),% eax"?

Я достаточно гуглил, но не смог понять, что означает скобка (). Кроме того, я вижу некоторый синтаксис как movl 8(%ebp), %eax

Может кто-нибудь предложить мне хорошую ссылку? Я не смог найти ни одного из 20 лучших результатов от Google.

Ответ 1

%eax - регистр EAX; (%eax) - это ячейка памяти, адрес которой содержится в регистре EAX; 8(%eax) - это ячейка памяти, адрес которой является значением EAX плюс 8.

Ответ 2

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.

Ответ 3

Они перемещают инструкции, перемещая данные из одного места в другое - в этих случаях из памяти в регистр:

register_eax = *(unsigned long *)register_eax;

Другой пример:

register_eax = *(unsigned long *)(register_ebp + 8);