这是什么汇编函数序言/结尾code。与RBP / RSP /离开干什么? [英] What is this assembly function prologue / epilogue code doing with rbp / rsp / leave?

查看:1818
本文介绍了这是什么汇编函数序言/结尾code。与RBP / RSP /离开干什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始学习汇编使用GCC编译器来组装我的code的MAC地址。不幸的是,对于学习如何做到这一点,如果你是一个初学者的资源非常有限。我终于设法找到了一些简单的示例code,我可以开始围绕说唱我的头,我知道了装配和正常运行。这里是code:

I am just starting to learn assembly for the mac using the GCC compiler to assemble my code. Unfortunately, there are VERY limited resources for learning how to do this if you are a beginner. I finally managed to find some simple sample code that I could start to rap my head around, and I got it to assemble and run correctly. Here is the code:

.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

的注释说明了在code一些事情(我有点明白什么线2 - 5做),但我不明白这个最意思。我明白了什么寄存器以及每个在这里注册( RBP RSP ESP 和 EAX )的用途以及他们是多么大,我也理解(通常情况下)堆栈是什么,但是这仍然会在我头上。谁能告诉我到底是什么这是在干什么?此外,任何人都可以点我一个很好的教程,适合初学者的方向是什么?

The comments explain some things in the code (I kind of understand what lines 2 - 5 do), but I dont understand what most of this means. I do understand the basics of what registers are and what each register here (rbp, rsp, esp and eax) is used for and how big they are, I also understand (generally) what the stack is, but this is still going over my head. Can anyone tell me exactly what this is doing? Also, could anyone point me in the direction of a good tutorial for beginners?

推荐答案

堆栈是如下的 LIFO原则。而在日常生活中栈(外部计算机,我的意思)向上生长,在x86和x86-64的处理器堆栈向下增长。请参阅第86堆栈 维基教科书的文章(但是请考虑到了code范例在Intel语法的32位x86 code,和你的code是在AT&放大器64位X86-64 code; T语法)

Stack is a data structure that follows LIFO principle. Whereas stacks in everyday life (outside computers, I mean) grow upward, stacks in x86 and x86-64 processors grow downward. See Wikibooks article on x86 stack (but please take into account that the code examples are 32-bit x86 code in Intel syntax, and your code is 64-bit x86-64 code in AT&T syntax).

所以,你的code做什么(我在这里的解释是与英特尔的语法):

So, what your code does (my explanations here are with Intel syntax):

push %rbp

RBP 堆放,切实从 RSP (减去8,因为的大小RBP 是8个字节),然后存储 RBP [SS:RSP]。

Pushes rbp to stack, practically subtracting 8 from rsp (because the size of rbp is 8 bytes) and then stores rbp to [ss:rsp].

所以,在Intel语法推RBP 切实做到这一点:

So, in Intel syntax push rbp practically does this:

sub rsp, 8
mov [ss:rsp], rbp

然后:

mov     %rsp, %rbp

这是显而易见的。刚 RSP 的值保存到 RBP

This is obvious. Just store the value of rsp into rbp.

subl    $8, %esp

尤其减去8,并将其存储到尤其。其实这是在你的code中的错误,即使它不会引起问题在这里。有32位寄存器(任何指令 EAX EBX ECX EDX EBP 尤其 ESI EDI )作为目的地的X86-64设置相应的64位寄存器的最上面的32位( RAX RBX RCX RDX RBP RSP RSI RDI )为零,导致堆栈指针指向下方的4吉布限制的地方,有效地做这个(英特尔语法):

Subtract 8 from esp and store it into esp. Actually this is a bug in your code, even if it causes no problems here. Any instruction with a 32-bit register (eax, ebx, ecx, edx, ebp, esp, esi or edi) as destination in x86-64 sets the topmost 32 bits of the corresponding 64-bit register (rax, rbx, rcx, rdx, rbp, rsp, rsi or rdi) to zero, causing the stack pointer to point somewhere below the 4 GiB limit, effectively doing this (in Intel syntax):

sub rsp,8
and rsp,0x00000000ffffffff

编辑:添加子的后果ESP,8 下面

然而,这会导致的存储器小于4吉布的计算机上没有问题。在具有超过4吉布内存的计算机,它可能会导致分段错误。 离开在code进一步跌破返回一个理智的价值 RSP 。一般在X86-64 code你不需要尤其从来没有(不包括可能一些优化调整或)。为了修复这个bug:

However, this causes no problems on a computer with less than 4 GiB of memory. On computers with more than 4 GiB memory, it may result in a segmentation fault. leave further below in your code returns a sane value to rsp. Generally in x86-64 code you don't need esp never (excluding possibly some optimizations or tweaks). To fix this bug:

subq    $8, %rsp

的说明到目前为止是标准的条目顺序(更换 $ 8个根据堆栈使用)。 维基教科书对86的功能和堆栈帧一个有用的文章(但同样注意,它使用32与英特尔的语法比特x86汇编,而不是64位X86-64组装与AT&安培; T语法)

The instructions so far are the standard entry sequence (replace $8 according to the stack usage). Wikibooks has a useful article on x86 functions and stack frames (but note again that it uses 32-bit x86 assembly with Intel syntax, not 64-bit x86-64 assembly with AT&T syntax).

然后:

movl    $0, %eax

这是显而易见的。商店0到 EAX 。这有什么好做的堆栈。

This is obvious. Store 0 into eax. This has nothing to do with the stack.

leave

这是等同于 MOV RSP,RBP 然后按流行RBP

ret

而这一点,最后,设置裂口来保存在值[SS:RSP]返回,有效code指针返回到该过程被称为,并增加了8〜 RSP

And this, finally, sets rip to the value stored at [ss:rsp], effective returning the code pointer back to where this procedure was called, and adds 8 to rsp.

这篇关于这是什么汇编函数序言/结尾code。与RBP / RSP /离开干什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆