AT&T x86主组件,
我想翻译程序集
line 1: subq $8, %rsp
line 2: movq %r11, (%rsp)
line 3: movq %rdi, %rdx
line 4: sarq $63, %rdx
line 5: movq %rdi,%rax
line 6: xorq %rdx,%rax
line 7: subq %rdx,%rax
line 8: movq (%rsp), %r11
line 9: add $8, %rsp
line 10: ret %r11据我所理解,%rsp是堆栈指针,这里的堆栈指针为qword字节创建了8个字节的空间。
它在C里看起来像这样吗?
int main() {
long x;
return 0:
}那么在第3行会发生什么我不确定。我认为%rdi寄存器进入%rdx。但是,在C代码中,这种情况会是怎样的呢?在我看来,没有任何东西被绑在登记簿上?
希望有人能帮我穿过1-3线!
发布于 2019-09-16 15:15:45
mov %src_reg, %dst_reg将src复制到dst。mov指令始终是一个副本。
RDI持有第一个整数/指针函数arg,在x86-64 System调用约定中。
ret %r11是非法语法。你不可能从反汇编程序那里得到这个。
在弹出返回地址后,ret不需要使用arg或imm16就可以添加到RSP中。(适用于x86-64系统V不使用的被调用的持久性有机污染物公约。而且,main将没有任何堆栈args;它们都适合于寄存器)。
无论如何,sar按reg宽度-1(向所有位广播符号位)和XOR / SUB看起来就像有符号2的补码整数的绝对值成语。
在这个(和其他)调用约定中,返回值以RAX表示。(或者是int main,在EAX。但是这个函数看起来不像main,除非它声明了long argc而不是标准的int。)
因此,可以是long foo(long x)返回绝对值,并将其存储到volatile本地并从其重新加载。但是,为什么编译器会认为%r11中有任何有用的东西。
它显然是在启用优化的情况下编译的,因为它没有将RBP设置为堆栈指针,而使用GCC或非常老的clang,因为它使用的是sub $8,%rsp而不是虚拟推送。
或者是手写的;这可能是阅读%r11的唯一解释。也许是一个定制的呼叫约定,而不是x86-64系统V?
https://stackoverflow.com/questions/57955424
复制相似问题