Интерпретация режима адресации памяти для x86 в Linux - PullRequest
0 голосов
/ 06 января 2019

Я читаю Программирование с нуля Джонатаном Бартлеттом . Автор обсуждает режим адресации памяти и утверждает, что общая форма адресации памяти такова:

ADDRESS_OR_OFFSET (%BASE_OR_OFFSET, %INDEX, MULTIPLIER)

где конечный адрес рассчитывается следующим образом:

FINAL_ADDRESS = ADDRESS_OR_OFFSET + %BASE_OR_OFFSET + MULTIPLIER * %INDEX.

Также указывается, что если какая-то часть не учитывается, она просто заменяется нулем в уравнении. ADDRESS_OR_OFFSET и MULTIPLIER должны быть константами, в то время как другие элементы должны быть регистрами. Похоже, что это единственные общие правила.

Пока все хорошо.

Затем автор обсуждает режим косвенной адресации и приводит в качестве примера:

movl (%eax), %ebx

, который перемещает значение по адресу, сохраненному в регистре eax, в регистр ebx.

Чтобы это сработало, (%eax) следует интерпретировать как 0(%eax,0,0), а не 0(0,%eax,0). Есть ли дополнительное правило, обеспечивающее такое толкование?

1 Ответ

0 голосов
/ 06 января 2019

Объяснение в книге не на 100% верно. Архитектура x86 имеет следующие 32-битные режимы адресации:

$imm                         immediate     result = imm
%reg                         register      result = reg
disp(%reg)                   indirect      result = MEM[disp + reg]
disp                         direct        result = MEM[disp]
disp(%base, %index, %scale)  SIB           result = MEM[disp + base + index * scale]

В режимах SIB (масштаб / индекс / основание) и косвенной адресации disp можно не указывать для смещения 0 байт. В режиме адресации SIB дополнительно base и index можно не указывать для шкалы 0, индекса 0; масштаб не может быть опущен на самом деле. Обратите внимание, что когда я говорю «пропустить», пропускается только значение; запятая оставлена. Например, (,,1) означает «операнд SIB без смещения, без основания, без индекса и 1 шкалы».

В 64-битном режиме дополнительно доступен режим относительной rip:

disp(%rip)                   rip relative  result = MEM[disp + rip]

Этот режим адресации полезен для написания независимого от позиции кода.

16-битные режимы имеют разные режимы адресации, но на самом деле они не имеют значения, поэтому я не буду их подробно останавливать.

Итак, для вашего примера: это легко понять, потому что на самом деле это косвенный режим адресации, а не SIB режим адресации с eax в качестве регистра и без смещения.

...