Как определить, загружены ли регистры справа налево или наоборот

При просмотре вывода gdb и рассмотрении вызовов сборки обычно я могу найти команду с использованием жестко заданных значений, чтобы определить, загружаются ли регистры справа налево или наоборот.

Обычно что-то вроде следующего:

  sub     rsp, 16

или

  sub     16, rsp 

Но в других случаях невидимые значения не видны. Все, что я вижу, это следующие вызовы:

(gdb) disassemble
 Dump of assembler code for function main:
 0x0000000100000f54 <main+4>:    mov    $rdi,%r15
 0x0000000100000f59 <main+9>:    mov    $rsi,%r14
 0x0000000100000f60 <main+16>:   mov    $rdx,%r13
 0x0000000100000f67 <main+23>:   mov    $ecx,$r12d
 End of assembler dump.

Как определить, обрабатываются ли значения слева направо или наоборот?

Ответ 1

Обычно, инструменты Gnu используют синтаксис AT & T. Вы можете сказать, что это синтаксис AT & T из-за наличия маленьких символов, таких как предшествующие литералы $ и предшествующие регистры %. Например, эта инструкция:

sub    $16, %rax

очевидно, использует синтаксис AT & T. Он вычитает 16 из значения в регистре rax и сохраняет результат обратно в rax.

В синтаксисе AT & T операнд назначения находится справа:

insn   source, destination     # AT&T syntax

Существует также синтаксис Intel. Это повсеместно распространено на платформах Windows и обычно также доступно как опция для инструментов Gnu/Linux. Синтаксис Intel не укомплектован - например:

sub   rax, 16

который совпадает с инструкцией AT & T выше, он вычитает 16 из значения в регистре rax и сохраняет результат в регистре rax.

В синтаксисе Intel операнд назначения всегда находится слева:

insn  destination, source     ; Intel syntax

Чтобы быть абсолютно уверенным в том, какую версию у вас есть, вам нужно будет проверить настройки вашего дизассемблера/отладчика и посмотреть, какой синтаксис он настроен для использования, но он обычно мертв-прост, чтобы сразу рассказать посмотрев, есть ли там символические украшения (мертвая отдача для синтаксиса AT & T).

Резюме:

  • Если регистры имеют префикс % → Синтаксис AT & T; src, dst.
  • В противном случае, неукрашенные регистры → Синтаксис Intel и rarr; dst, src.

Если вы каким-то образом столкнулись с кодом, который не использует никаких регистров (???), другой хороший эвристический ключ заключается в том, что синтаксис Intel будет предусматривать спецификаторы размеров (например, DWORD, QWORD и BYTE) в связанный операнд, тогда как синтаксис AT & T добавит суффикс (l, q, b и т.д.) к самой мнемонике команд.