在汇编中,很多函数都以以下序言开头:
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;
}
以下是我的两个问题:
- 在 MainEntry 函数中,有一个
push %rbp
,然后是一个push %rbx
。为什么要将 RBX 推入堆栈? - 如果我理解正确,
sub $0x48, %rsp
在堆栈上分配了 0x48 字节,lea 0x80(%rsp), %rbp
将堆栈向下移动了 0x80 字节,并将其作为基址指定。 RBP 最终会在局部堆栈帧的什么位置,并且它是如何到达那里的?
mov rsp, rbp
。rbp
被推入栈中,但它被分配的方式很奇怪。它为向量分配了0x48
字节,然后将0x80
字节移动到堆栈下方以设置rbp
。 - user2914191lea 0x80(%rsp),%rbp
设置了帧(通过将0x80字节添加到堆栈指针并将其存储在rbp
中),并且本地变量的寻址是相对于rbp
的。如果不使用帧指针,则本地变量将相对于rsp
寻址。 - 1201ProgramAlarmrbp
与main()的rbp
是相同的值。因此,main
和MainEntry
使用相同的基指针,这就是为什么有如此大的偏移量0x80字节
的原因。 - user2914191