为什么函数序言中没有 `mov %rsp, %rbp` 语句?

3
在汇编中,很多函数都以以下序言开头:
00000001004010e0: main(int, char**)+0    push    %rbp
00000001004010e1: main(int, char**)+1    mov     %rsp,%rbp

有些函数,比如下面这个,不会:

                              int MainEntry(){
                                       MainEntry():
0000000100401104: MainEntry()+0          push    %rbp
0000000100401105: MainEntry()+1          push    %rbx
0000000100401106: MainEntry()+2          sub     $0x48,%rsp
000000010040110a: MainEntry()+6          lea     0x80(%rsp),%rbp
                                        vector<int> v;
0000000100401112: MainEntry()+14         lea     -0x60(%rbp),%rax
0000000100401116: MainEntry()+18         mov     %rax,%rcx
0000000100401119: MainEntry()+21         callq   0x100401b00 <std::vector<int, std::allocator<int> >::vector()>
                                        return 0;
000000010040111e: MainEntry()+26         mov     $0x0,%ebx
0000000100401123: MainEntry()+31         lea     -0x60(%rbp),%rax
0000000100401127: MainEntry()+35         mov     %rax,%rcx
000000010040112a: MainEntry()+38         callq   0x100401b20 <std::vector<int, std::allocator<int> >::~vector()>
000000010040112f: MainEntry()+43         mov     %ebx,%eax
                                     }

这是编译成以下代码的C++代码:

int main(int c, char** args){
    MainEntry();
    return 0;
}

int MainEntry(){
    vector<int> v;
    return 0;
}

以下是我的两个问题:

  1. MainEntry 函数中,有一个 push %rbp,然后是一个 push %rbx。为什么要将 RBX 推入堆栈?
  2. 如果我理解正确,sub $0x48, %rsp 在堆栈上分配了 0x48 字节,lea 0x80(%rsp), %rbp 将堆栈向下移动了 0x80 字节,并将其作为基址指定。 RBP 最终会在局部堆栈帧的什么位置,并且它是如何到达那里的?
1个回答

3
  1. 根据调用约定,rbx 被推入堆栈,因为它在函数调用之间需要保留。

  2. 此函数没有启用帧指针。在不启用帧指针的编译中,rbp 只是另一个通用寄存器。

关于标题中的问题(现已改进)
push rsp, rbp 指令不存在。 push 始终只接受一个参数。也许您想问的是为什么没有推送 rbp。答案是因为没有使用它,因此不需要任何指令来保留它。


是的,我在标题中想说的是 mov rsp, rbprbp 被推入栈中,但它被分配的方式很奇怪。它为向量分配了 0x48 字节,然后将 0x80 字节移动到堆栈下方以设置 rbp - user2914191
MainEntry使用帧指针。lea 0x80(%rsp),%rbp设置了帧(通过将0x80字节添加到堆栈指针并将其存储在rbp中),并且本地变量的寻址是相对于rbp的。如果不使用帧指针,则本地变量将相对于rsp寻址。 - 1201ProgramAlarm
2
我刚刚检查了寄存器,看起来MainEntry()的rbp与main()的rbp是相同的值。因此,mainMainEntry使用相同的基指针,这就是为什么有如此大的偏移量0x80字节的原因。 - user2914191

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接