【问题标题】:How to determine if the registers are loaded right to left or vice versa如何确定寄存器是否从右到左加载,反之亦然
【发布时间】:2018-10-12 08:17:28
【问题描述】:

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

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

【问题讨论】:

  • 如果寄存器有 % 前缀 => AT&T 语法 => src, dst 顺序。否则,朴素 => 英特尔语法 => dst, src.

标签: assembly x86 cpu-registers att intel-syntax


【解决方案1】:

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

sub    $16, %rax

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

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

insn   source, destination     # AT&T syntax

还有 Intel 语法。这在 Windows 平台上无处不在,通常也可作为 Gnu/Linux 工具的一个选项。英特尔语法朴素——例如

sub   rax, 16

这与上面的 AT&T 指令相同——它从 rax 寄存器中的值中减去 16,然后将结果存储回 rax 寄存器中。

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

insn  destination, source     ; Intel syntax

要绝对确定您拥有的是哪个版本,您需要检查反汇编器/调试器的设置并查看它配置为使用的语法,但一目了然通常非常简单通过查看是否存在符号装饰(AT&T 语法的致命赠品)。

总结:

  • 如果寄存器有 % 前缀 → AT&T 语法 → src, dst 顺序。
  • 否则,未经修饰的寄存器 → Intel 语法 → dst, src 顺序。

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

【讨论】:

  • 对于具有两个以上操作数的指令,AT&T 语法将英特尔的列表颠倒过来。例如pshufd $0xE4, %src, %dst.
  • 我用这个信息更新了AT&T tag wiki(包括一些常见问题的好 dup 目标的链接,使用这个作为操作数顺序的答案)
猜你喜欢
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 2017-08-29
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
  • 1970-01-01
相关资源
最近更新 更多