首页
学习
活动
专区
圈层
工具
发布

C语言函数的栈帧详解

一、栈 简单来说栈的主要特点有: 一个限定表尾进行删除(出栈)和插入(入栈)操作的线性表,其过程类似与压子弹与退子弹(后进先出)。...引用百度百科:C语言中,每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量。从这句话中,可以提炼以下几点信息: 栈帧是一块因函数运行而临时开辟的空间。...int b = 20; 00AA1435 mov dword ptr [ebp-14h],14h int ret = 0; 00AA143C mov dword...在函数栈帧、局部变量创建完毕后,进行Add()函数运算过程: PLAINTEXT c = a + b; 00AA13E5 mov eax,dword ptr [ebp+8] 00AA13E8...3.3.4 函数返回 PLAINTEXT return c; 00AA13EE mov eax,dword ptr [ebp-8] 将返回值传递至寄存器eax中,因此在函数调用结束函数栈帧被销毁时

2.8K20
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C语言函数调用及栈帧结构

    如图: 二、栈帧的建立 首先要明白几个地方:每一个函数都有自己的栈帧空间,并且独占自己的栈帧空间, 当前正在运行的函数的栈帧总是在栈顶。...栈帧状态值:保存前栈帧的顶部和底部(实际上只保存前栈帧的底部,前栈帧的顶部可以通过栈帧平衡计算得到),用于在本栈被弹出后恢复出上一个栈帧。...然后继续执行下一条语句:mov ebp,esp即把esp的值赋给ebp,这样,ebp也就指向了现在esp的位置 然后sub esp 0C0h 这样就为main函数开辟了一段空间然后将ebx、esi、edi...如此一来,几乎所有的c函数都由如下两个指令开 始: push ebp mov ebp, esp 下一步,fun必须为它的局部变量分配空间,同时,也必须为它可能用到的一些临时变量分配 空间。...比如,foo中的一些C语句可能包括复杂的表达式,其子表达式的中间值就必须得有地方存放。

    2.4K30

    图文解析函数栈帧

    前言:         在C语言程序中,编写函数是我们必不可少的技能,但是我们通常会忽视了函数在内存中的开辟过程,一般地我们通过将一些功能封装到函数中,通过将实参传入,在主函数main.c中调用函数,但是事实上...一、函数栈帧是什么? 在程序运行过程中,函数栈帧(Function Stack Frame) 是栈内存中为单个函数调用分配的一块独立内存区域。...= add(a, b); // 调用add,接收返回值 printf("c=%d", c); return 0; } 阶段 1:初始状态 如下图所示:                ...阶段2:调用 add 前         main 准备参数,压栈,C 语言函数参数默认从右向左压栈(先压最右边的参数y,再压左边的x),然后压入 “返回地址”(add 执行完后,main 要回到的代码位置...int c = 5); 后续执行printf("c=%d", c),输出c=5,程序结束。

    47820

    【C语言】函数——栈帧的创建和销毁

    ✨作者:@平凡的人1 ✨专栏:《C语言从0到1》 ✨一句话:凡是过往,皆为序章 ✨说明: 过去无可挽回, 未来可以改变 ---- 目录 前言 什么是栈 什么是函数的栈帧 认识相关寄存器和汇编指令...下面我们要先来理解一些概念 什么是栈 在学习C语言中,我们关注内存中的3个区域,栈区、堆区和静态区 那究竟什么是栈呢?...⏩ 栈(stack)是现代计算机程序里最为重要的概念之一,几乎每一个程序都使用了栈,没有栈就没有函 数,没有局部变量,也就没有我们如今看到的所有的计算机语言。...("%d\n", ret); 00BE1863 mov eax,dword ptr [ebp-20h] 00BE1866 push eax 00BE1867 push 0BE7B30h 00BE186C...12地址处的数字加到eax寄存中 00BE1779 mov dword ptr [ebp-8],eax //将eax的结果保存到ebp-8的地址处,其实就是放到z中 return z; 00BE177C

    1K10

    【C语言底层】函数栈帧的创建和销毁

    函数的使用也要开辟栈帧 esp存入函数低位置的地址,叫做栈顶指针,ebp存入函数高位置的地址,叫做栈底指针。...打开反汇编,我们可以看到汇编语言对程序的操作,这里push叫压栈,push ebp就是将一个叫做ebp的量压到栈顶上边(这里涉及到监视窗口可以监视到ebp确实是地址小于的正好在 __tmainCRTStartup...,这是call指令的下一条指令,以便call返回时继续使用 这里的汇编语言指令在前面都说到过,我们跳过继续说 注意这里先传b再传a,传参的顺序是从右往左的,在汇编指令中我们可以很明显的发现...20h了,也就是z的值给了c:z在销毁前把值传给eax,eax在00C21453这一步时将值传给ebp-20h,在这个位置的值就是c。...到现在,我把函数栈帧的创建和销毁的过程大致梳理了一遍,我在学完之后有一种恍然大悟的感觉,希望这篇能够帮到大家。

    38210

    C语言内功的修炼--函数栈帧创建和销毁

    目录 什么是栈帧 什么是栈 栈帧的创建与销毁 main函数调用过程  Add函数的调用过程 ---- 什么是栈帧 简单地说 程序的执行过程可看作连续的函数调用,而C语言中,每个栈帧对应着一个未运行完的函数...每个函数的每次调用(通常使用堆栈实现),都有它自己独立的一个栈帧 这个栈帧中保存了该函数的返回地址和局部变量维持着所需要的各种信息 所以栈帧也叫过程活动记录,是编译器用来实现过程/函数调用的一种数据结构...从逻辑来看 栈帧就是一个函数执行的环境:函数参数、函数的局部变量、函数执行完后返回到哪里等 ---- 什么是栈 在详解之前我们还得明白一点栈: 栈,也叫堆栈,是一种数据结构,具有先进后出的特点...(类似子弹上弹夹) 在函数栈帧创建过程中,内存从高地址往低地址使用 寄存器edp存放了指向函数栈帧栈底的地址(高地址) 寄存器esp存放了指向函数栈帧栈顶的地址(低地址) esp和ebp...共同维护函数栈帧 ---- 栈帧的创建与销毁 在VS2013下逐步调试add函数向大家展示并讲解栈帧的创建和销毁过程 int Add(int x, int y) { int z = 0;

    78020

    C语言——F函数的栈帧的创建和销毁

    三、函数栈帧的创建和销毁解析 1、什么是栈?...栈(stack)是现代计算机程序里最为重要的概念之一,几乎每一个程序都使用了栈,没有栈就没有函数,没有局部变量,也就没有我们如今看到的所有的计算机语言。         ...转入目标函数 jump:通过修改eip,转入目标函数,进行调用 ret:恢复返回地址,压入eip,类似pop eip命令 lea:预加载,装入有效地址的意思,它的操作数就是地址 3、解析函数栈帧的创建和销毁...= 0; 00BE1849 mov dword ptr [ebp-20h],0 //将0存储到ebp-20h的地址处,ebp-20h的位置其实是c变量 //以上汇编代码表示的变量a,b,c的创建和初始化...,这就是局部的变量的创建和初始化 //其实是局部变量的创建时在局部变量所在函数的栈帧空间中创建的 //调用Add函数 c = Add(a, b); //调用Add函数时的传参 //其实传参就是把参数push

    46410

    C语言:底层剖析——函数栈帧的创建和销毁

    一、究竟什么是函数栈帧      C语言的使用是面向过程的, 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。...所以C语言的程序都是以函数作为基本单位的,如果能够深入理解函数,无疑对于c语言会有更深刻地理解,修炼自己的内功,那么函数是如何调用的?函数返回值是如何返回的?...栈(stack)是现代计算机程序里最为重要的概念之一,几乎每一个程序都使用了栈,没有栈就没有函数,没有局部变量,也就没有我们如今看到的所有的计算机语言。        ...转入目标函数 jump:通过修改eip,转入目标函数,进行调用 ret:恢复返回地址,压入eip,类似pop eip命令 3.3 函数栈帧的创建与销毁解析 3.3.1 预备知识 1、每一次函数调用,都需要为本次函数调用开辟空间...这样我们可以确定,invoke_main函数也有自己的栈帧,main函数和add函数也有自己的栈帧,每个栈帧都有自己的edp和esp来维护栈帧空间!

    1.4K11

    【C语言】函数栈帧的创建和销毁(逐步分析)

    什么是函数栈帧 我们在写C语言代码的时候,经常会把一个独立的功能抽象为函数,所以C程序是以函数为基本单位的。 那函数是如何调用的?函数的返回值又是如何返回的?函数参数是如何传递的?...Add(int x, int y) { int z = 0; z = x + y; return z; } int main() { int a = 10; int b = 20; int c...= 0; c = Add(a, b); printf("%d\n", c); return 0; } 首先我们先建立main函数的栈帧空间,但我们思考一下,main函数是不是也有可能被其他函数调用那...,接下来就是把值放进去,int a=10,dword是双字节的意思,将a的值放在ebp-8这个空间里 接下来就把b, c也像a一样分别放入对应的位置  接下来就是传参,将ebp-14h也就是b的空间放入...最后将承载着z的值也就是两数和的值的寄存器eax,将值付给ebp-20h也就是c的地址  此时c就为30了  结论 局部变量是怎么创建的 创建好函数栈帧后,我们初始化一部分函数空间,而局部变量就在这个空间里分配一个空间

    45410

    C++|Compiler|活动记录(栈帧)

    需要注意的是,在支持闭包的语言中,活动记录未必在栈上,因为函数返回仍需访问其中的变量,因此活动记录应作为环境保存下来。...意思是这个参数并不是开始就求值,而是在函数的每次实际调用再进行解析。...需要取址 传引用 被嵌套的函数调用 以下情况参数在特定环境下必须进内存,并不能断定 参数大小大于寄存器大小 register有特殊需求不能被占用(例如汇编要求占用寄存器) 局部变量数量多于可用寄存器数目 在C中...---- 嵌套过程 静态链(Static Link) 嵌套函数中,内部函数调用的栈帧可见外部函数调用的栈帧中的变量。...如果儿子1调用儿子2,那么事实上儿子1是通过父亲访问到的儿子2,因此不能直接传儿子1的栈帧,而是先回溯到父亲的栈帧,再把父亲的栈帧指针作为第一个参数传递给儿子2.

    1.7K40

    C语言进阶:(一)深度剖析函数栈帧:从创建到销毁

    这些问题的答案,都隐藏在 “函数栈帧” 这一核心概念中。 函数栈帧是理解 C 语言底层执行机制的关键,它不仅能解答上述疑问,更能帮助我们排查数组越界、野指针等底层 bug。...本文将基于 VS2019 编译器,从栈的基础概念出发,结合汇编指令与实战代码,一步步拆解函数栈帧的创建、函数调用、参数传递、返回值带回及栈帧销毁的完整过程,带你看透 C 语言函数执行的底层逻辑。...1.3 理解函数栈帧的核心价值 掌握函数栈帧的创建与销毁逻辑,能帮我们彻底搞懂以下 C 语言的核心问题: 局部变量是如何创建和存储的? 为什么未初始化的局部变量值是随机的?...总结 函数栈帧的知识虽然偏底层,但它能帮你从根源上理解 C 语言的执行逻辑,让你在编写代码时更严谨,排查 bug 时更高效。...希望本文能带你走进 C 语言的底层世界,让你对 C 语言有更深刻的认识!谢谢大家的支持!

    20010

    FFmpeg开发笔记(三十)解析H.264码流中的SPS帧和PPS帧

    其中视频编码层专注如何高效地表达视频的数据内容,而网络抽象层负责格式化数据并提供头信息,以便视频内容能够适应各种环境的数据传输。...每个视频帧都包含至少一个NAL单元,对于I帧、P帧来说,因为内部数据比较多,所以可能会分为多个NAL单元。...起始码往后的一个字节,代表当前帧的类型,常见的帧类型有下列六种:0x67,类型值为7,为SPS帧,表示序列参数集。0x68,类型值为8,为PPS帧,表示图像参数集。...0x65,类型值为5,为IDR帧,即IDR图像,也称为关键帧。0x41,类型值为1,为SLICE分片,表示P帧。0x01,类型值为1,为SLICE分片,表示B帧。...在每个H.264流的开头,都会出现这样的序列:SPS帧→PPS帧→IDR帧→其余SLICE,并且SPS、PPS、IDR三种帧必定是搭配出现的,缺一不可,如果少了其中任何一帧,都会导致后续视频流解码异常。

    3.7K10
    领券