Как определить, загружены ли регистры справа налево или наоборот
При просмотре вывода 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
и т. д.) к самой инструкции мнемоника.