GCC 编译的二进制文件中的冗余寄存器值?

Redundant register values in GCC-compiled binary?

好的,我正在尝试学习逆向工程和 x64 汇编。例如,我在 C:

中编写了这个小测试程序
#include <stdio.h>

int square(int num) {
        return num * num;
}

int main() {
        int ans = square(5);
        printf("%d", ans);
}

这会产生以下 square 函数的汇编代码:

push   rbp
mov    rbp,rsp
mov    DWORD PTR [rbp-0x4],edi
mov    eax,DWORD PTR [rbp-0x4]
imul   eax,eax
pop    rbp
ret

这对我来说有点奇怪,因为 edi 是函数参数,我相信它会存储在堆栈中并加载回 eax,然后在那里相乘?为什么不跳过第 3 行和第 4 行而直接 imul edi, edi?
所以我打开了 radare2 并这样做了,但是现在程序 returns 看似随机数,我在猜测内存地址?

有人可以向我解释为什么 GCC 使用这个看似冗余的寄存器,以及我在尝试修补二进制文件时做错了什么吗?

您没有启用优化,所以您正在查看调试代码。使用 -O3,输出为:

请注意您的问题,您需要 分配给 eax,因为 eax 将 return 值存储在 x86 应用程序中.