【问题标题】:Question about local variable registers in x86-64 Assembly language关于x86-64汇编语言中局部变量寄存器的问题
【发布时间】: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

标签: c assembly x86-64


【解决方案1】:

不,它没有为c 赋值。

参数的值被移动到堆栈中。具体来说,rdx 中的值被复制到-48(%rbp)。所以当编译器想要改变c的值时,它会写入-48(%rbp)

在后面的代码中,rdx 只是用作临时寄存器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多