如何确定寄存器是从右到左加载,反之亦然 [英] How to determine if the registers are loaded right to left or vice versa
问题描述
在查看 gdb 输出和查看程序集调用时,通常我可以找到一个使用硬编码值的命令来确定寄存器是从右向左加载,反之亦然.
When reviewing gdb output and looking at the assembly calls, usually I can find a command using hard-coded values to determine whether the registers are being loaded right to left or vice versa.
通常类似于以下内容:
sub rsp, 16
或
sub 16, rsp
但其他时候,上面的值是不可见的.我所看到的只是如下调用:
But other times, no values like above are visible. All I see are calls like the following :
(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.
如何确定值是从左到右处理还是从左到右处理?
How does one determine if values are processed left to right or vice versa?
推荐答案
通常,Gnu 工具使用 AT&T 语法.您可以通过小符号的存在来判断它是 AT&T 语法,例如 $
前面的文字和 %
前面的寄存器.例如,这条指令:
Normally, Gnu tools use AT&T syntax. You can tell that it is AT&T syntax by the presence of little symbols, like the $
preceding literals, and the %
preceding registers. For example, this instruction:
sub $16, %rax
显然使用 AT&T 语法.它从 rax
寄存器中的值中减去 16,并将结果存储回 rax
.
is obviously using AT&T syntax. It subtracts 16 from the value in the rax
register, and stores the result back in rax
.
在 AT&T 语法中,目标操作数位于右侧:
In AT&T syntax, the destination operand is on the right:
insn source, destination # AT&T syntax
还有英特尔语法.这在 Windows 平台上无处不在,通常也可作为 Gnu/Linux 工具的一个选项.Intel 语法朴素——例如:
There is also Intel syntax. This is ubiquitous on Windows platforms, and usually also available as an option for Gnu/Linux tools. Intel syntax is unadorned—e.g.:
sub rax, 16
与上面的 AT&T 指令相同——它从 rax
寄存器中的值中减去 16,并将结果存储回 rax
寄存器.
which is the same as the AT&T instruction above—it subtracts 16 from the value in the rax
register, and stores the result back in the rax
register.
在 Intel 语法中,目标操作数总是在左边:
In Intel syntax, the destination operand is always on the left:
insn destination, source ; Intel syntax
要绝对确定您拥有哪个版本,您需要检查反汇编器/调试器的设置并查看它配置使用的语法,但通常一目了然通过查看是否存在象征性装饰(AT&T 语法的无用功).
To be absolutely certain of which version you've got, you'd need to check the settings for your disassembler/debugger and see what syntax it is configured to use, but it's usually dead-simple to tell at a glance just by looking to see if the symbolic adornments are there (a dead give-away for AT&T syntax).
总结:
- 如果寄存器有
%
前缀 → AT&T 语法 →src, dst
顺序. - 否则,未修饰的寄存器 → Intel 语法 →
dst, src
顺序.
- If the registers have a
%
prefix → AT&T syntax →src, dst
order. - Otherwise, unadorned registers → Intel syntax →
dst, src
order.
如果您以某种方式最终查看了不使用任何寄存器 (???) 的代码,另一个很好的启发式线索是 Intel 语法将预先设置大小说明符(如 DWORD
、QWORD
和 BYTE
) 到关联的操作数,而 AT&T 语法将附加一个后缀 (l
, q
、b
等)到指令助记符本身.
If you've somehow ended up looking at code that doesn't use any registers (???), another good heuristic clue is that Intel syntax will prepend size specifiers (like DWORD
, QWORD
, and BYTE
) to the associated operand, whereas AT&T syntax will append a suffix (l
, q
, b
, etc.) to the instruction mnemonic itself.
这篇关于如何确定寄存器是从右到左加载,反之亦然的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!