gpt4 book ai didi

gcc - 为什么生成的程序集将 edi 移动到堆栈上的变量?

转载 作者:行者123 更新时间:2023-12-02 16:57:59 25 4
gpt4 key购买 nike

我是汇编的新手,试图理解以下函数的 objdump:

int nothing(int num) {
return num;
}

这是结果(linux、x86-64、gcc 8):

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

我的问题是: 1. edi从哪里来?阅读一些介绍文档后,我的印象是 [rbp-0x4] 将包含 num。 2. 从上面可以看出,edi 显然包含参数。但是 [rbp-0x4] 扮演什么角色呢?为什么不只是 mov eax, edi

谢谢!

最佳答案

  1. Where does edi come from?

... From the above, apparently edi contains the argument.

这是调用约定(适用于 Linux 和许多其他操作系统):

这些操作系统的所有编程语言都在 rdi 中传递第一个参数。结果(返回值)在 rax 中传递。

并且由于您的 C 编译器将 int 解释为 32 位,因此仅使用 rdirax 的低 32 位 - 这是 edieax

Windows 编程语言在 rcx 中传递第一个参数...

But then what role does [rbp-0x4] play?

这里使用 rbp 主要有历史原因。在 16 位代码中(因为它在 1980 年代和 1990 年代的 PC 中使用)不可能使用 sp 寄存器(对应于 rsp)在堆栈上寻址数据.唯一允许在堆栈上轻松寻址值的寄存器是 bp 寄存器(对应于 rbp)。

即使在 32 位或 64 位代码中,使用 rsp 而不是使用 rbp 来编写寻址局部变量(在堆栈上)的编译器也更加困难.

编译器在知道 C 函数中做了什么之前生成了汇编代码的前 3 条指令。编译器将值放在堆栈上,因为您可以在代码中执行类似 address = &num 的操作。然而,当 num 位于寄存器中时,这是不可能的,但只有当 num 位于内存中时。

Why not just mov eax, edi?

如果您告诉编译器优化代码,它会在生成第一条汇编程序指令之前先检查 C 函数的内容。它会发现不需要将值放入内存。

在这种情况下,代码确实看起来像这样:

mov eax, edi
ret

关于gcc - 为什么生成的程序集将 edi 移动到堆栈上的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55563152/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com