如何确定寄存器是从右向左加载还是从右向左加载

How to determine if the registers are loaded right to left or vice versa

在查看 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.

如何确定值是从左到右还是从右到右处理?

通常,Gnu 工具使用 AT&T 语法。您可以通过小符号的存在来判断它是 AT&T 语法,例如 $ 前面的文字和 % 前面的寄存器。例如这条指令:

sub    , %rax

显然是在使用 AT&T 语法。它从 rax 寄存器中的值减去 16,并将结果存储回 rax.

在 AT&T 语法中,目标操作数在右侧:

insn   source, destination     # AT&T syntax

还有英特尔语法。这在 Windows 平台上无处不在,通常也可作为 Gnu/Linux 工具的选项使用。 Intel 语法是未修饰的例如:

sub   rax, 16

与上面的AT&T指令相同——将rax寄存器中的值减去16,并将结果存回rax寄存器。

在 Intel 语法中,目标操作数总是在左边:

insn  destination, source     ; Intel syntax

要完全确定您使用的是哪个版本,您需要检查 disassembler/debugger 的设置并查看配置使用的语法,但通常很容易分辨一目了然,只需查看符号装饰是否存在(AT&T 语法的死赠品)。

Summary:

  • If the registers have a % prefix → AT&T syntax → src, dst order.
  • Otherwise, unadorned registers → Intel syntax → dst, src order.

如果您以某种方式最终查看了不使用任何寄存器的代码 (???),另一个很好的启发式线索是 Intel 语法将在前面加上大小说明符(如 DWORDQWORD, 和 BYTE) 到相关的操作数,而 AT&T 语法将在指令助记符本身附加一个后缀 (l, q, b, 等等) .