在查看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语法,例如
$
前面的文字和%
前面的寄存器 . 例如,这条指令:显然是使用AT&T语法 . 它从
rax
寄存器中的值中减去16,并将结果存储在rax
中 .在AT&T语法中,目标操作数在右侧:
还有英特尔语法 . 这在Windows平台上无处不在,通常也可作为Gnu / Linux工具的选项 . 英特尔语法是无用的 - 例如:
这与上面的AT&T指令相同 - 它从
rax
寄存器中的值中减去16,并将结果存储回rax
寄存器 .在Intel语法中,目标操作数始终位于左侧:
为了确定你所拥有的版本,你需要检查你的反汇编程序/调试程序的设置,看看它配置使用的语法,但通常看起来很简单 . 看看符号装饰是否存在(AT&T语法的死亡赠品) .
如果你使用任何寄存器(???),另一个好的启发式线索是英特尔语法将大小说明符(如
DWORD
,QWORD
和BYTE
)添加到相关的操作数,而AT&T语法将附加后缀(l
,q
,b
等)指令助记符本身 .