gpt4 book ai didi

macos - 这个汇编函数序言/尾声代码对 rbp/rsp/leave 有什么作用?

转载 作者:行者123 更新时间:2023-12-04 10:26:38 27 4
gpt4 key购买 nike

我刚刚开始学习使用 GCC 编译器组装我的代码的 mac 汇编。不幸的是,如果您是初学者,学习如何做到这一点的资源非常有限。我终于找到了一些简单的示例代码,我可以开始用它来敲打我的脑袋,然后我就可以正确地组装和运行它了。这是代码:

.text                                           # start of code indicator.
.globl _main # make the main function visible to the outside.
_main: # actually label this spot as the start of our main function.
push %rbp # save the base pointer to the stack.
mov %rsp, %rbp # put the previous stack pointer into the base pointer.
subl $8, %esp # Balance the stack onto a 16-byte boundary.
movl $0, %eax # Stuff 0 into EAX, which is where result values go.
leave # leave cleans up base and stack pointers again.
ret

注释解释了代码中的一些内容(我有点理解第 2 - 5 行的作用),但我不明白其中大部分是什么意思。我确实了解什么是寄存器的基础知识以及这里的每个寄存器( rbprspespeax )的用途以及它们的大小,我也了解(通常)堆栈是什么,但这仍然在我的脑海中。谁能告诉我这是在做什么?另外,有人可以指出我为初学者提供的好教程的方向吗?

最佳答案

堆栈是一个跟在 LIFO principle 之后的数据结构。日常生活中的堆栈(我的意思是在计算机之外)向上增长,而 x86 和 x86-64 处理器中的堆栈向下增长。请参阅 Wikibooks article on x86 stack(但请注意代码示例是采用 Intel 语法的 32 位 x86 代码,而您的代码是采用 AT&T 语法的 64 位 x86-64 代码)。

所以,你的代码做了什么(我在这里的解释是用 Intel 语法):

push %rbp

rbp 压入堆栈,实际上是从 rsp 中减去 8(因为 rbp 的大小为 8 个字节),然后将 rbp 存储到 [ss:rsp]

因此,在英特尔语法 push rbp 中实际上是这样做的:
sub rsp, 8
mov [ss:rsp], rbp

然后:
mov     %rsp, %rbp

这是显而易见的。只需将 rsp 的值存储到 rbp 中。
subl    $8, %esp

esp 中减去 8 并将其存储到 esp 中。实际上,这是您代码中的一个错误,即使它在这里没有引起任何问题。在X86-64集的32位寄存器( eaxebxecxedxebpespesiedi)作为目的地的任何指令相应的64位寄存器( raxrbxrcx的顶端32位, rdxrbprsprsirdi )为零,导致堆栈指针指向低于 4 GiB 限制的某个位置,有效地执行此操作(以 Intel 语法):
sub rsp,8
and rsp,0x00000000ffffffff

编辑: 添加了下面 sub esp,8 的结果。

但是,这在内存小于 4 GiB 的计算机上不会造成任何问题。在内存超过 4 GiB 的计算机上,可能会导致段错误。代码中更下方的 leave 将一个合理的值返回给 rsp 。通常在 x86-64 代码中,您永远不需要 esp(不包括可能的一些优化或调整)。要修复此错误:
subq    $8, %rsp

到目前为止的指令是标准的入口序列(根据堆栈使用情况替换 $8)。 Wikibooks has a useful article on x86 functions and stack frames(但请再次注意,它使用具有 Intel 语法的 32 位 x86 程序集,而不是具有 AT&T 语法的 64 位 x86-64 程序集)。

然后:
movl    $0, %eax

这是显而易见的。将 0 存储到 eax 中。这与堆栈无关。
leave

这相当于 mov rsp, rbp 后跟 pop rbp
ret

最后,将 rip 设置为存储在 [ss:rsp] 的值,有效地将代码指针返回到调用此过程的位置,并将 8 添加到 rsp

关于macos - 这个汇编函数序言/尾声代码对 rbp/rsp/leave 有什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14296088/

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