【发布时间】:2020-03-04 21:04:43
【问题描述】:
我的任务是将 x86-64 汇编代码转换回简单的 C 函数。我正在使用的 C 函数有 4 个参数(long a、long b、long c、long d)。正如所料,汇编代码的开头以
开头movq %rdi, -32(%rbp)
movq %rsi, -40(%rbp)
movq %rdx, -48(%rbp)
movq %rcx, -56(%rbp)
稍后在代码中再次使用这些寄存器,例如
movq -40(%rbp), %rax
imulq -48(%rbp), %rax
movq %rax, %rdx
movq -32(%rbp), %rax
addq %rdx, %rax
movq %rax, -24(%rbp)
我的问题是,上面的代码在第三行是否为 (long c) 分配了一个值,或者该寄存器是否在第一个代码 sn-p 期间被清空,并且只是在此代码中用作通用寄存器情况。
【问题讨论】:
-
这基本上是 Why does clang produce inefficient asm with -O0 (for this simple floating point sum)? 的副本 - 当您编译反优化调试版本时,编译器基本上会忘记语句之间的寄存器(
-O0是 gcc 和 clang 的默认值)。寄存器不能“清空”,mov也不会将源操作数归零。如果您希望优化代码有意义/看起来像人类可能会做的那样,请查看优化代码。 -
@Havenard:在函数入口时将寄存器参数溢出到堆栈是“调试”构建的 100% 正常(gcc/clang 默认为
-O0,您可以为icc手动指定,也)。查看调试 asm 通常是在浪费时间 - How to remove "noise" from GCC/clang assembly output?。调用约定是 x86-64 System V,从 RDI 和 RSI 中可以看出,它们是传递参数的 regs。返回值将仅包括__int128的 RDX 或大于 8 字节但 -
不,它没有为
c赋值。参数的值被移动到堆栈中。具体来说,rdx中的值被复制到-48(%rbp)。所以当编译器想要改变c的值时,它会写入-48(%rbp)。在后面的代码中,rdx只是用作临时寄存器。 (注意:我假设您是正确的,rdx对应于参数c。) -
@user3386109 谢谢这是我一直在寻找的答案
-
@user3386109:“我在 SO 上有唯一的 x86-64 金色徽章,我批准了这条消息”:P