C温故补缺(十五):栈帧
栈帧
概念
栈帧:也叫过程活动记录,是编译器用来实现过程/函数调用的一种数据结构,每次函数的调用,都会在调用栈(call stack)上维护一个独立的栈帧(stack frame)
栈帧的内容
函数的返回地址和参数
临时变量:包括函数的非静态局部变量,以及编译器自动生成的其他临时变量
函数调用上下文
两个指针:ebp又称帧指针(frame pointer),指向当前栈帧的底部; esp,又称栈针织(stack pointer),始终指向栈顶
函数调用
函数调用过程中分:函数调用者(caller)和被调用的函数(callee)
调用者需要知道被调用函数的返回值
被调用函数需要知道传入的参数和返回的地址
步骤:
参数入栈:将参数按照调用约定依次压入系统栈
返回地址入栈:将当前代码区调用指令的下一条指令地址压入栈,供函数返回时继续执行,也就是保护现场和恢复现场
代码跳转:处理器将代码区跳转到被调用函数的入口处
栈帧调整:
将调用者的ebp压入栈,保存指向栈底ebp地址(用于恢复现场),此时esp指向新的栈顶位置
将当前栈帧切换到新栈帧(将esp值装入ebp,跟新栈底),此时ebp指向栈顶,
给新栈帧分配空间
函数返回
步骤:
保存被调用函数的返回值到eax寄存器
恢复esp同时收回局部变量空间
将上一个栈帧底部位置恢复到ebp
弹出当前元素栈顶元素,从栈中取到返回地址,并跳转到该位置,也就是再回到调用者,执行后续代码
举例说明
c代码:
int sum(int x,int y){
int z=x+y;
return z;
}
int main(){
int a=1;
int b=3;
int c=sum(a,b);
}
汇编,且关闭编译器优化-O0
.file "test.c"
.text
.globl sum
.def sum; .scl 2; .type 32; .endef
.seh_proc sum
sum:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $16, %rsp
.seh_stackalloc 16
.seh_endprologue
movl %ecx, 16(%rbp)
movl %edx, 24(%rbp)
movl 16(%rbp), %edx
movl 24(%rbp), %eax
addl %edx, %eax
movl %eax, -4(%rbp)
movl -4(%rbp), %eax
addq $16, %rsp
popq %rbp
ret
.seh_endproc
.def __main; .scl 2; .type 32; .endef
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $48, %rsp
.seh_stackalloc 48
.seh_endprologue
call __main
movl $1, -4(%rbp)
movl $3, -8(%rbp)
movl -8(%rbp), %edx
movl -4(%rbp), %eax
movl %eax, %ecx
call sum
movl %eax, -12(%rbp)
movl $0, %eax
addq $48, %rsp
popq %rbp
ret
.seh_endproc
.ident "GCC: (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0"
过程详解:
补充:整个过程中虽然看不到RIP,但它一直被使用,RIP每次都指向下一条将要运行的指令
每次取出一条指令时,RIP就会自动偏移,指向下一条指令,如图:
当发生函数调用时,也就是call时,callq 指令会自动将rip压入栈,并将rip指向被调用的函数,如
先RIP指向 callq f()
,下一次执行就是调用函数f(),查看此时的rsp
接着执行该指令
ip跳到了f()内的第一条指令push %rbq
,再查看rsp
rsp中存入了0x00401586
,正是call的下一条指令的位置
且也可以查看变量在栈帧内的存储形式
将1赋值给变量b,即mov 1 -4(%bp)
,查看内存
就是在bp的偏移4字节处
再来看ret,ret是将之前存的RIP给出栈,经过sub分配空间然后再add释放空间,pop rbp后,rsp刚好在旧的rip处
此时执行ret,会自动执行pop rip
,也就恢复了现场
也就是说:
call f
的本质是:
push %rip
mov f,%rip
ret
的本质是:
pop %rip
C温故补缺(十五):栈帧的更多相关文章
- Kinect for Windows SDK v2.0 开发笔记 (十五) 手势帧
(转载请注明出处) 使用SDK: Kinect for Windows SDK v2.0 public preview1409 同前面,由于SDK未完毕,不附上函数/方法/接口的超链接. 这次最 ...
- “全栈2019”Java多线程第三十五章:如何获取线程被等待的时间?
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第二十五章:生产者与消费者线程详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第十五章:当后台线程遇到finally
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java异常第十五章:异常链详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- “全栈2019”Java第九十五章:方法中可以定义静态局部内部类吗?
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- “全栈2019”Java第八十五章:实现接口中的嵌套接口
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- “全栈2019”Java第七十五章:内部类持有外部类对象
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- “全栈2019”Java第六十五章:接口与默认方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- “全栈2019”Java第五十五章:方法的静态绑定与动态绑定
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
随机推荐
- Typora破解下载
Typora破解下载 文章指路
- 2022-9-5 JavaSE note
Java SE 1.IDEA基本操作 psvm + 回车 : main() 方法声明 sout + 回车 : = System.out.println(); Ctrl + D : 把当前行复制到下一行 ...
- 使用 Win2D 实现融合效果
1. 融合效果 在 CSS 中有一种实现融合效果的技巧,使用模糊滤镜(blur)叠加对比度滤镜(contrast)使两个接近的元素看上去"粘"在一起,如下图所示: 博客园的 Cho ...
- 第六章:Django 综合篇 - 10:消息框架 message
在网页应用中,我们经常需要在处理完表单或其它类型的用户输入后,显示一个通知信息给用户. 对于这个需求,Django提供了基于Cookie或者会话的消息框架messages,无论是匿名用户还是认证的用户 ...
- MinIO Client完全指南
官方文档地址:http://docs.minio.org.cn/docs/master/minio-client-complete-guide 下载,添加云存储服务参考这篇文章:https://www ...
- 域名服务DNSmasq搭建
假设该服务端主机ip是:192.168.80.100 服务端安装(yum方式) yum install dnsmasq -y # 配置系统文件 # cp /etc/resolv.conf /etc/r ...
- td-agent的v2,v3,v4版本区别
官方地址:https://docs.fluentd.org/quickstart/td-agent-v2-vs-v3-vs-v4
- OSF--网络类型
ABR:区域边界路由器ASBR:自治区域系统边界路由器区域部署原则: 存在vlink本地网络一定是有问题的.他只是作为一种过度技术,在vlink里无法实现认证! 配置: [r2-ospf-a ...
- 用AR Engine手部骨骼跟踪能力实现虚拟手表试戴
AR技术的落地应用,推动着电商领域的不断升级,通过增强现实为用户带来了虚拟与现实结合的AR购物体验.如AR试衣.AR试鞋.AR试妆等功能的出现让用户在手机上就能体验产品的佩戴效果,可以让用户更直观.更 ...
- Linux-->vi和vim编辑器的基本操作
vim编辑器介绍 vi或者vim就是对linux下的文本进行编辑的一种编辑器比如说a.cpp文件这种 Linux会内置vi文本编辑器 Vim可以简单的认为vi的增强版 Linux是区分大小写的! 用法 ...