Abs*_*ful 1 assembly gcc x86-64 calling-convention
我是汇编的新手,试图了解以下函数的 objdump:
int nothing(int num) {
return num;
}
Run Code Online (Sandbox Code Playgroud)
这是结果(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
Run Code Online (Sandbox Code Playgroud)
我的问题是: 1.edi
从哪里来?阅读一些介绍文档,我的印象是[rbp-0x4]
将包含num
. 2. 从上面可以看出,edi 显然包含了这个论点。但是,它[rbp-0x4]
扮演什么角色呢?为什么不只是mov eax, edi
?
谢谢!
- 哪里
edi
来的呢?...从上面,显然edi包含论点。
这是调用约定(适用于 Linux 和许多其他操作系统):
这些操作系统的所有编程语言都在rdi
. 结果(返回值)传入rax
.
并且由于您的 C 编译器解释int
为 32 位,因此仅使用rdi
和的低 32 位rax
- 即edi
和eax
。
Windows 的编程语言在rcx
...中传递第一个参数
但是,它
[rbp-0x4]
扮演什么角色呢?
rbp
在这里使用主要有历史原因。在 16 位代码中(如 1980 年代和 1990 年代 PC 中使用的那样),无法使用sp
寄存器(对应于rsp
)对堆栈上的数据进行寻址。唯一允许在堆栈上轻松寻址值的bp
寄存器是寄存器(对应于rbp
)。
即使在 32 位或 64 位代码中,编写一个使用rsp
而不是使用rbp
.
编译器在知道 C 函数中做了什么之前会生成汇编代码的前 3 条指令。编译器将值放在堆栈上,因为您可以address = &num
在代码中执行类似操作。然而,当num
在寄存器中时这是不可能的,而只有当num
位于内存中时才可能。
为什么不只是
mov eax, edi
?
如果你告诉编译器优化代码,它会在生成第一条汇编指令之前先检查 C 函数的内容。它会发现不需要将值放入内存中。
在这种情况下,代码确实如下所示:
mov eax, edi
ret
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
538 次 |
最近记录: |