如何确定寄存器是从右到左加载,反之亦然

Unh*_*ion 2 x86 assembly cpu-registers att intel-syntax

在查看gdb输出并查看汇编调用时,通常我可以找到一个使用硬编码值的命令来确定寄存器是从右到左加载,反之亦然.

通常类似于以下内容:

  sub     rsp, 16
Run Code Online (Sandbox Code Playgroud)

要么

  sub     16, rsp 
Run Code Online (Sandbox Code Playgroud)

但有时候,没有像上面这样的值可见.我所看到的只是如下调用:

(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.
Run Code Online (Sandbox Code Playgroud)

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

Cod*_*ray 8

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

sub    $16, %rax
Run Code Online (Sandbox Code Playgroud)

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

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

insn   source, destination     # AT&T syntax
Run Code Online (Sandbox Code Playgroud)

还有英特尔语法.这在Windows平台上无处不在,通常也可作为Gnu/Linux工具的选项.英特尔语法简洁 - 例如:

sub   rax, 16
Run Code Online (Sandbox Code Playgroud)

这与上面的AT&T指令相同 - 它从rax寄存器中的值中减去16 ,并将结果rax存回寄存器中.

在Intel语法中,目标操作数始终位于左侧:

insn  destination, source     ; Intel syntax
Run Code Online (Sandbox Code Playgroud)

为了确定你已经拥有哪个版本,你需要检查反汇编程序/调试程序的设置,看看它配置使用的语法,但通常看起来很简单.看看符号装饰是否存在(AT&T语法的死亡赠品).

摘要:

  • 如果寄存器有%前缀→AT&T语法→ src, dst顺序.
  • 否则,简单的寄存器→Intel语法→ dst, src顺序.

如果你已经莫名其妙地结束在看代码,不使用任何寄存器(???),另一个很好的启发线索就是英特尔语法将预先考虑大小说明(如DWORD,QWORDBYTE)的相关操作,而AT&T语法将追加一个后缀(l,q,b等)到指令助记符本身.