[英]C & Nasm64 combination - stack alignment, epilogue, prologue - OSX 64
[英]What is this assembly function prologue / epilogue code doing with rbp / rsp / leave?
我刚刚开始使用GCC编译器来学习汇编我的代码。 不幸的是,如果你是初学者,有非常有限的资源来学习如何做到这一点。 我终于设法找到了一些简单的示例代码,我可以开始说清楚了,我得到它来组装并正确运行。 这是代码:
.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行的内容),但我不明白大多数这意味着什么。 我确实理解了寄存器的基础知识以及这里的每个寄存器( rbp
, rsp
, esp
和eax
)的用途以及它们有多大,我也理解(通常)堆栈是什么,但这仍然是我的头。 谁能告诉我到底这是做什么的? 还有,有人能指出我为初学者提供一个好的教程吗?
堆栈是遵循LIFO原则的数据结构。 虽然日常生活中的堆栈(我的意思是计算机外)向上增长,但x86和x86-64处理器中的堆栈却向下增长。 请参阅x86堆栈上的Wikibooks文章 (但请注意,代码示例是Intel语法中的32位x86代码,并且您的代码是AT&T语法中的64位x86-64代码)。
那么,你的代码做了什么(我的解释是英特尔语法):
push %rbp
将rbp
推送到堆栈,实际上从rsp
减去8(因为rbp
的大小是8个字节),然后将rbp
存储到[ss:rsp]
。
所以,在Intel语法中, push rbp
实际上是这样做的:
sub rsp, 8
mov [ss:rsp], rbp
然后:
mov %rsp, %rbp
这很明显。 只需将rsp
的值存储到rbp
。
subl $8, %esp
从esp
减去8并将其存储到esp
。 实际上这是你的代码中的一个错误,即使它在这里没有引起任何问题。 在x86-64中作为目标的32位寄存器( eax
, ebx
, ecx
, edx
, ebp
, esp
, esi
或edi
)的任何指令都会设置相应64位寄存器的最高32位( rax
, rbx
, rcx
, rdx
, rbp
, rsp
, rsi
或rdi
)为零,导致堆栈指针指向低于4 GiB限制的位置,实际上这样做(在Intel语法中):
sub rsp,8
and rsp,0x00000000ffffffff
编辑:增加sub esp,8
后果sub esp,8
以下。
但是,这会导致内存小于4 GiB的计算机出现问题。 在具有4个以上GiB内存的计算机上,可能会导致分段错误。 leave
下面将进一步在你的代码返回一个理智的价值rsp
。 通常在x86-64代码中,您不需要esp
never(不包括可能的一些优化或调整)。 要修复此错误:
subq $8, %rsp
到目前为止的指令是标准的入口序列(根据堆栈使用情况替换$8
)。 Wikibooks有一篇关于x86函数和堆栈框架的有用文章 (但请注意,它使用的是32位x86程序集,采用Intel语法,而不是采用AT&T语法的64位x86-64程序集)。
然后:
movl $0, %eax
这很明显。 将0存入eax
。 这与堆栈无关。
leave
这相当于mov rsp, rbp
后跟pop rbp
。
ret
最后,这将rip
设置为[ss:rsp]
存储的值,有效地将代码指针返回到调用此过程的位置,并向rsp
添加8。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.