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

При просмотре вывода 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 → dst, src порядок.

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

Другие вопросы по тегам