ebp/栈帧/call stack

article/2025/10/3 21:56:59

一.什么是ebp?

(1)ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。
(2)EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈(包含多个栈帧)最上面一个栈帧的底部。

二.什么是栈帧?

1.栈帧——整个系统调用路径上的某个函数占用的一个系统栈片段(帧)。

2.下图展示了两个栈帧的系统栈。

3.从上图可知,当前函数对应的栈帧的栈底(第一个压栈值)实际上压入的正是ebp寄存器的值,而这个值正是其caller栈帧的栈底

4.ebp的值只会在发生函数调用的时候变化,并且是esp寄存器的一个快照。

push    ebp  
mov     ebp,esp

上面两句话的意思是将ebp推入栈中,之后让ebp等于esp

为什么这么做呢?因为ebp作为一个用于寻址的固定值是有时间周期的。只有在某个函数执行过程中才是固定的,在函数调用与函数执行完毕后会发生改变。

在函数调用之前,将调用者的函数(caller)的ebp存入栈,以便于在执行完毕后恢复现场是还原ebp的值。

5.从上面main函数的反汇编也可以看出,栈帧的结构如下:

三.再举个简单的例子

C代码:

#include<stdio.h>int func(int a, int b)
{return a+b;
}int main(int argc, char **argv)
{int c = 0;c = func(0x5, 0x6);return 1;
}

对应的汇编代码:

func:pushl %ebpmovl %esp,%ebpmovl 8(%ebp),%eaxaddl 12(%ebp),%eaxjmp .L1
.L1:leave               //movl ebp,esp; popl ebp, 回到func函数栈base pointer,弹出main的ebpret                 //popl eip(由call func那条指令压入的call func返回地址)
main:pushl %ebpmovl %esp,%ebp      //main函数的栈base pointersubl $4,%esp        //栈中预留func的返回值占用的4字节空间movl $0,-4(%ebp)    //将栈中预留func的返回值空间清0pushl $6            //压入func参数,从最后一个参数到第一个参数依次压栈pushl $5call func           //1.push eip; 2.跳转到func标号去执行movl %eax,-4(%ebp)  //func的返回值写入栈中预留的空间movl $1,%eax        //设置main的返回值为1jmp .L2
.L2:leave               //相当于以下两条指令,movl ebp,esp; popl ebp, 回到main函数栈base pointer,弹出main的调用者的ebpret                 //popl eip

栈帧变化说明:

 

四.通过栈帧追踪某个函数的call stack

1.功能实现函数

// Record the current call stack in pcs[] by following the %ebp chain.
// 记录当前调用getcallerpcs的函数call stack的算法
void
getcallerpcs(void *v, uint pcs[])
{uint *ebp;int i;ebp = (uint*)v - 2;         // 获取caller's caller的起始栈帧/* 一共记录10层调用栈 */for(i = 0; i < 10; i++){if(ebp == 0 || ebp < (uint*)KERNBASE || ebp == (uint*)0xffffffff)break;pcs[i] = ebp[1];          // saved %eip ———— 调用函数后返回地址ebp = (uint*)ebp[0];      // saved %ebp}for(; i < 10; i++)pcs[i] = 0;
}

2.假设有如下调用栈

kfree(char *v)acquire(&kmem.lock);        //void acquire(struct spinlock *lk)getcallerpcs(&lk, lk->pcs);

3.getcallerpcs函数算法的实现原理展示在下图

参考:

实例讲解 xv6 的锁 - 知乎


http://chatgpt.dhexx.cn/article/mWRNq94u.shtml

相关文章

栈帧详解

一. 理解栈帧 栈帧是什么&#xff0c;我们基本的理解是栈帧是栈帧也叫过程 活动记录&#xff0c;是 编译器用来实现过程/ 函数调用的一种数据结构。通俗来说栈帧就时C语言函数在调用的过程中的调用原理&#xff0c;就是当我们执行一个函数操作的时候&#xff0c;它的内部是如何…

EBP 和 ESP 详解

基本概念&#xff1a; &#xff08;1&#xff09;ESP&#xff1a;栈指针寄存器(extended stack pointer)&#xff0c;其内存放着一个指针&#xff0c;该指针永远指向系统栈最上面一个栈帧的栈顶。 &#xff08;2&#xff09;EBP&#xff1a;基址指针寄存器(extended base poin…

基于生命周期的开发方法——迭代开发方法

迭代开发方法 上一篇原型方法只是一种需求验证的手段&#xff0c;如果将其思想运用到整个开发过程&#xff0c;使得每个阶段的任务经过反复多次&#xff0c;或者将分析、设计、实施的周期反复多次&#xff0c;通过一次次迭代&#xff0c;不断在原来的基础上完善和修正&#xf…

2.迭代开发的过程是怎么样的

敏捷开发系列文章目录 在讨论PO如何给团队讲好故事这个问题之前&#xff0c;先给大家了解一些基本的敏捷概念&#xff0c;然后讲讲我们敏捷团队构成与整个敏捷开发的过程。 当初敏捷老师讲课的时候就跟我们所过&#xff0c;敏捷没有什么具体的形式&#xff0c;每个敏捷团队可能…

RUP之动态结构:迭代开发

迭代过程一般分为四个阶段&#xff1a;初始、细化、构造和移交&#xff0c;简称为I,E,C和T。每个阶段以一个重要的里程碑(milestone)结束。 初始(Inception)阶段 确定最终产品的构想及其业务用例、并定义项目范围 初始阶段以生命周期目标(LCO)里程碑为结束点 细化(Elaborat…

开发模式(敏捷开发,瀑布式开发,螺旋型开发,迭代开发,devOps开发)

一. 敏捷开发 以人为核心、迭代、循序渐进的开发方式 简化文档&#xff0c;提取文档重点&#xff0c;主要在于人与人之间的沟通&#xff0c; 对开发产品进行迭代&#xff0c;最终完成开发。 迭代&#xff1a;迭代是指把一个复杂且开发周期很长的开发任务&#xff0c;分解为很…

敏捷开发-快速迭代

&#xff08;转自:http://blog.csdn.net/xiaoxian8023/article/details/8883791&#xff09; 今天跟大家分享的是“敏捷开发、快速迭代”。我们大都采用的是“瀑布开发模式”&#xff0c;有了问题&#xff0c;就得返工&#xff0c;虽然最终的产品会比较齐全完善&#xff0c;但是…

一文搞定软件过程模型——瀑布模型、增量式开发/增量开发与迭代开发的区别

软件开发比较经典的过程模型有&#xff1a; 瀑布模型&#xff1a;该模型将基本的过程活动、描述、开发、有效性验证和进化&#xff0c;看成是一些界限分明的独立的过程阶段&#xff0c;例如&#xff0c;需求描述阶段、软件设计阶段、实现阶段、测试阶段等。增量式开发&#xf…

软件迭代开发流程

如果对python自动化测试、web自动化、接口自动化、移动端自动化、大型互联网架构技术、面试经验交流等等感兴趣的老铁们&#xff0c;可以关注我。我会在公众号&#xff08;程序员阿沐&#xff09;/群里&#xff08;810119819&#xff09;不定期的发放免费的资料链接&#xff0c…

迭代开发流程

转载于:https://www.cnblogs.com/gispathfinder/p/8747869.html

git 迭代开发分支流程规范

前言 Git 的名称太响了&#xff0c;相信大家都听说过&#xff0c;鼎鼎大名的同性交友网站 GitHub 就是基于 Git 作为唯一的版本库格式进行托管的平台。本篇不详细介绍 Git 的使用&#xff0c;仅介绍基于 Git 的开发分支流程规范&#xff0c;需要对 Git有一定的了解。 简述 G…

迭代开发和增量开发

&#xff08;转自&#xff1a;http://blog.csdn.net/l12345678/article/details/5642851&#xff09; “迭代”和“增量”是敏捷软件开发中的两个重要概念。弄清楚“迭代”和“增量”以及其依据&#xff0c;我们就可以在实际的操作中有章法可循。 为什么要迭代&#xff1f; 我们…

转」最佳方案:迭代式开发

前言 Fred Brooks 在 25 年前就曾写到&#xff1a;“不要指望一次成功&#xff0c;无论如何你都要这样。” 敏捷开发&#xff0c;小步快跑&#xff0c;持续迭代&#xff0c;不断改进&#xff0c;产品升级。 在用例需要之前&#xff0c;不要添加数据成员 在代码之前编写测试 …

alert意为:警告、警报。

在JavaScript代码中&#xff0c;alert的作用是弹出一个浏览器对话框&#xff0c;"JS代码"为提示对话框的内容 <body><script type"text/JavaScript"> alert("提交成功&#xff01;我会尽快与你取得联系"); </script></body…

JS中alert和alter

JS中没有alter&#xff0c;只用alert&#xff0c;alert表示输出后面的语句

js 的 alert函数问题

alert是js人非常熟悉的东西&#xff0c;可以用来调试&#xff0c;写在这里是想警醒我自己&#xff0c;以后再遇到这样的问题的时候谨记这么修改。 看一个简单例子&#xff1a; <body><div οnmοuseοveralert((function(){return"abc";}()))>abc</…

Alert 提示框的使用

1. Alert 基本的使用 1.1 实现 /// 提示框 struct AlertBootcamp: View {State var showAlert: Bool falseState var alertType: MyAlerts? nilState var alertTitle: String ""State var alertMessage: String ""State var backgroundColor: Color …

java中的alert是什么意思_javascript 中如何使用alert?

alert不行的,要变通的话还是用showModalDialog试试吧. window.showModalDialog()方法用来创建一个显示HTML内容的模态对话框&#xff0c;由于是对话框&#xff0c;因此它并没有一般用window.open()打开的窗口的所有属性。 window.showModelessDialog()方法用来创建一个显示HTML…

Grafana面板(panel):报警功能(alerts)

文章目录 alerts(报警设置)Create a Grafana managed alerting ruleAdd Grafana managed rule alert notifications增加一个notification channel alert报警邮件中的链接地址错误如何配置alert产生的报警如何删除&#xff1f;alert设置注意事项 alerts(报警设置) 注意&#xf…

alertmanger 入门

alertmanger 安装 tags: alertmanager 文章目录 alertmanger 安装1. 简介2. 安装2.1 二进制包部署 AlertManager2.1.1 下载2.1.2 创建 alertmanager 配置文件2.1.3 启动2.1.4 查看状态 2.2 docker 安装2.3 关联 Prometheus 与 Alertmanager 2. 配置文件说明3. 配置示例&#x…