为什么在功能序言中没有“mov %rsp, %rbp”

Why is there no `mov %rsp, %rbp` in function prologue?

本文关键字:mov %rsp %rbp 功能 为什么      更新时间:2023-10-16

在汇编中,许多函数以以下序言开头:

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. rbx被推送到堆栈上,因为调用约定规定它在调用中保留。

  2. 此函数在没有帧指针的情况下编译。 rbp 只是在没有帧指针的情况下编译时的另一个通用寄存器。

关于标题中的问题(现已改进(
push rsp, rbp指令不存在。 push总是接受一个论点。也许你的意思是问为什么rbp不被推动。答案是没有人使用它,因此不需要任何说明来保存它。