栈结构 BP 进程虚拟地址空间
2011-09-29 20:22
344 查看
栈结构(参数入栈顺序跟调用方式有关,这里以C语言默认的CDECL为例(参数由右向左进入堆栈)):
| ....................| (栈底方向,高位地址)
| 参数3 |
| 参数2 |
| 参数1 |
| 返回地址 |
-| 上一层[EBP] |
| 局部变量2 |
| 局部变量1 |
|.....................| (栈顶方向,低位地址)
栈一直随着函数调用的深入,一直想栈顶方向压下去。每次调用函数时候,先压函数参数(从右往左顺序压),再压入函数调用下条指令的地址(由call完成)。接着进入调用函数体中先执行 pushq %rbp; movq %rsp, %rbp(一般已经由编译器加入到函数头中了),接着就是吧函数体中的局部变量压入栈中。再遇到函数的调用的嵌套则依此类推。(added by smsong)
pushq %rbp; movq %rsp, %rbp这两条指令实在大有深意:首先将rbp入栈,然后将栈顶指针rsp赋值给rbp。movq %rsp, %rbp这条指令表面上看是用rsp把原来rbp的值覆盖了,其实不然——因为给rbp赋值之前,原rbp值已被压栈(位于栈顶),而新的rbp又恰恰指向栈顶
此时rbp寄存器就已处于一个很重要的地位,该寄存器中存储着栈中的一个地址(原rbp入栈后的栈顶),从该地址为基准,向上(栈底方向)能获取返回地址、参数值,向下(栈顶方向)能获取函数局部变量值,而该地址处又存储着上一层函数调用时的rbp值!
进程的虚拟地址空间
| ....................|
| ....................|
|内核虚拟存储器| (高位地址)
|用户栈(运行时创建)|
|共享库的存储器的映射区域|
|运行时堆|
|读/写数据|
|只读的代码和数据|
|未用| (低位地址)
| ....................|
| ....................|
| ....................| (栈底方向,高位地址)
| 参数3 |
| 参数2 |
| 参数1 |
| 返回地址 |
-| 上一层[EBP] |
| 局部变量2 |
| 局部变量1 |
|.....................| (栈顶方向,低位地址)
栈一直随着函数调用的深入,一直想栈顶方向压下去。每次调用函数时候,先压函数参数(从右往左顺序压),再压入函数调用下条指令的地址(由call完成)。接着进入调用函数体中先执行 pushq %rbp; movq %rsp, %rbp(一般已经由编译器加入到函数头中了),接着就是吧函数体中的局部变量压入栈中。再遇到函数的调用的嵌套则依此类推。(added by smsong)
pushq %rbp; movq %rsp, %rbp这两条指令实在大有深意:首先将rbp入栈,然后将栈顶指针rsp赋值给rbp。movq %rsp, %rbp这条指令表面上看是用rsp把原来rbp的值覆盖了,其实不然——因为给rbp赋值之前,原rbp值已被压栈(位于栈顶),而新的rbp又恰恰指向栈顶
此时rbp寄存器就已处于一个很重要的地位,该寄存器中存储着栈中的一个地址(原rbp入栈后的栈顶),从该地址为基准,向上(栈底方向)能获取返回地址、参数值,向下(栈顶方向)能获取函数局部变量值,而该地址处又存储着上一层函数调用时的rbp值!
进程的虚拟地址空间
| ....................|
| ....................|
|内核虚拟存储器| (高位地址)
|用户栈(运行时创建)|
|共享库的存储器的映射区域|
|运行时堆|
|读/写数据|
|只读的代码和数据|
|未用| (低位地址)
| ....................|
| ....................|
相关文章推荐
- 脚本,查看一次性快速运行的程序的进程虚拟地址空间
- PE文件结构与虚拟地址空间
- 关于Windows编程中进程虚拟地址空间/虚拟内存及内存映射方面的资料
- 内存管理分析之一:Linux进程空间与虚拟地址的好处
- 进程虚拟地址空间之数据分区存放【转】
- 进程的虚拟地址空间,堆栈、堆、数据段、代码段
- Chap-6 6.4 进程虚拟地址空间分布
- 进程的虚拟地址空间,堆栈、堆、数据段、代码段
- 进程的虚拟地址空间,堆栈、堆、数据段、代码段(转)
- C的内存虚拟地址空间结构
- 进程的虚拟地址空间
- PE文件结构与虚拟地址空间
- linux和windows的进程的虚拟地址空间
- 进程虚拟地址空间
- 进程虚拟地址空间 程序编译链接过程
- 进程用户态虚拟地址空间上限测试
- 进程的虚拟地址空间划分
- 进程的虚拟地址空间——NULL指针分区
- 进程的虚拟地址空间
- PE文件结构与虚拟地址空间