什么是函数栈帧? 理解了函数栈帧能解决什么样的问题? 函数栈帧的创建和销毁解析! 调试工具:vs 2013。 什么是函数栈帧?...接下来是返回z: 这里有个小问题,就是Add函数已经完成任务了,里面的东西应该已经销毁了,怎么还能把Z的值返回到main函数里面去了呢?...其实很简单,看下面的指令:把ebp-8的值放到eax里面去,eax可是个寄存器啊,因此是不会因为程序退出而销毁的! ...执行add指令,让ebp加8,此时形参x和y已经销毁了,被回收了! 紧接着,把eax的值放到ebp-20h中去,也就是c的地址 最后,打印,然后结束程序,销毁main函数的栈帧。...PS:本人对函数栈帧的创建和销毁的拙见,请有大佬看到的其中不妥的问题时候,可以纠正我的问题。谢谢!
(本次的代码调试我使用的环境是VS2013版,其他版本可能会有细微差别,但大体步骤和内容是类似的) 1.源代码 为了演示这次函数栈帧的创建与销毁,我们将以一次简单的程序来作为范例。...3.函数栈帧的创建与销毁(重点) 该程序的汇编代码如下:(注释有每一步的原理) --- d:\c语言\函数栈帧hszz\函数栈帧hszz\hszz.c -------------------------...ptr [ebp-20h],eax //把eax的值也就是z的值赋值给变量c printf("%d\n", c); 00E91456 mov esi,esp //后面的内容是销毁...main函数,过程和销毁ADD函数类似,因此以下不再赘述 00E91458 mov eax,dword ptr [ebp-20h] 00E9145B push eax...main __tmainCRTStartup __mainCRTSartup 总结 以上就是今天要讲的内容,本文用一个范例介绍了函数栈帧的创建与销毁,文章开头所提出的问题也在文章正文中做出了解答。
3.函数栈帧的创建和销毁解析 3.1栈 栈( stack )是现代计算机程序里最为重要的概念之一,几乎每一个程序都使用了栈,没有栈就没有函数,没有局部变量,也就没有我们如今看到的所有的计算机语言。...在经典的计算机科学中,栈被定义为一种特殊的容器,用户可以将数据压入栈中(入栈 push ),也可以将已经压入栈中的数据弹出(出栈,pop ),但是栈这个容器必须遵守一条规则: 先入栈的数据后出栈 (First...在计算机系统中,栈则是一个具有以上属性的动态内存区域。程序可以将数据压入栈中,也可以将数据 从栈顶弹出。压栈操作使得栈增大,而弹出操作使得栈减小。...转入目标函数 jump :通过修改 eip ,转入目标函数,进行调用 ret :恢复返回地址,压入 eip ,类似 pop eip 命令 3.3解析函数栈帧的创建和销毁 3.3.1...2.这块空间的维护是使用了两个寄存器:esp ebp,ebp记录的是栈底的地址,esp记录的是栈顶的地址。 3.函数栈帧的创建和销毁过程,在不同的编译器上实现的方法大同小异。
那么通过学习函数栈帧的创建和销毁,以上困惑就会迎刃而解。...为了讲清楚函数栈帧,我们需要先做一些铺垫: 寄存器: eax ebx ecx edx ebp esp ebp、esp这2个寄存器中存放的是地址,这2个地址是用来维护函数栈帧的...每一个函数调用,都要在栈区创建一个空间 接下来,就正式开始介绍函数栈帧的创建和销毁 push ebp mov ebp,esp sub esp,0E4h push ebx push esi push...这个寄存器里面 pop edi pop esi pop ebx mov esp,ebp pop ebp ret add esp,8 mov dword ptr [ebp-20h],eax main函数的销毁和...Add函数的销毁类似,就不再进行演示了。
在函数调用时,每个函数都会创建一个对应的栈帧,并在函数返回时销毁它。了解函数栈帧的创建和销毁机制,有助于我们更好地管理内存和理解程序执行的过程。...二、函数栈帧的销毁 函数栈帧的销毁是在函数返回时进行的。在函数返回之前,需要将栈帧中的信息恢复并将其从栈中弹出。具体的销毁过程如下: 1....三、函数栈帧的创建和销毁过程中的注意事项 在函数栈帧的创建和销毁过程中,有一些注意事项需要我们注意。这些注意事项可以帮助我们更好地管理内存和避免潜在的问题。以下是一些常见的注意事项: 1....当出现异常时,函数栈帧的销毁过程可能会被打断,导致资源泄漏和内存泄漏等问题。因此,在函数中正确地处理异常,确保函数栈帧能够正常地销毁,是非常重要的。 5....总结: 函数栈帧的创建和销毁是程序执行过程中的重要环节,我们需要仔细考虑栈帧的大小、局部变量的生命周期、返回值的存储和传递等问题。
---- 函数栈帧的创建和销毁:: ebp,esp这两个寄存器中存放的是地址,这两个地址是用来维护函数栈帧的,edp被称为栈底指针,esp被称为栈顶指针。push:压栈:给栈顶放一个元素。...pop:出栈:给栈顶删一个元素,lea:加载有效地址。dword=4byte。...答:首先为此次函数调用创建函数栈帧,在函数栈帧找空间存放局部变量值。 2.为什么局部变量的值是随机值? 随机值是系统开辟完函数栈帧后系统随机放进去的。 3.函数是怎么传参的?...返回值并不会随着函数作用域的销毁而销毁,而是放在eax中准备返回,当通过pop出栈回到main函数中再将返回值放到局部变量中。
这两个地址是用来维护函数栈帧的。 每一次函数调用,都要在栈区创立一个空间。 什么是栈? 函数通过栈来实现控制转移、参数传递、局部变量的分配和释放3个功能。...栈被定义为一种特殊的容器,用户可以将数据压入栈中(入栈,push),也可 以将已经压入栈中的数据弹出(出栈,pop),但是栈这个容器必须遵守一条规则:先入栈的数据后出栈。...编写代码 详细解释栈帧创立和销毁过程 如下图所示,在栈区(计算机专门的内存空间),每个函数在栈区申请一块内存空间,称为函数栈帧。在调用哪个函数,esp和ebp就跑去维护哪个函数的栈帧。...eax是个寄存器,寄存器是不会退出就销毁的。ebp-8就是z,里面存放着30的值。等回到主函数时,再把eax的值拿出来用就行了。 三次pop弹出 再把ebp赋给esp。...然后再pop一下,把栈顶的元素弹出来,栈顶弹的是main函数的ebp。ebp的地址存在main函数当中,就是要让随着函数调用返回之后,随着栈帧的销毁,栈顶是很容易找到的,但是栈底不容易找到。
函数栈帧是函数调用过程中重要的数据结构,它存储了函数的局部变量、参数以及返回地址等信息。在函数调用过程中,函数栈帧的创建和销毁是由编译器根据函数代码生成的汇编指令来完成的。...本文将详细介绍函数栈帧的创建和销毁过程,并指出其中的关键细节,同时提供相应的优化方法。 以下是一些与函数栈帧相关的重要概念和特性: 1....为局部变量分配存储空间 在完成上述步骤后,编译器会在栈帧中为局部变量分配存储空间,并初始化其中的部分空间。 二、函数栈帧的销毁过程 1....指向下一个空闲位置 最后,当函数栈帧被销毁后,栈顶指针(ESP)会指向函数调用者的下一个空闲位置,以便继续执行调用者函数的代码。 三、优化方法 1....只要函数调用完了就销毁这些空间 如果在函数内部创建了静态变量,就不会销毁
寄存器 相关的汇编指令: 函数的调用堆栈 函数栈帧的创建 分析栈帧的创建: 为什么会出现“烫烫烫”: 分析main函数中的核心代码: 分析Add函数的传参 函数调用过程 函数栈帧的销毁下 结语✍ --...-- 前言 好的,各位,我们前面就已经学过函数的一些相关知识了,对函数也有了一定的了解,然后呢,今天我将通过这一篇博客给大家带来关于函数栈帧的创建和销毁的一些相关知识,让大家对于函数有更进一步的了解,增加自己的内在知识...如何理解"烫烫烫"的由来 只要理解了函数栈帧的创建和销毁,以上问题就能够很好的理解了,这也是本篇博客的主要目的。...注意:函数栈帧的创建和销毁过程,在不同的编译器上实现的方法大同小异。本篇博客基于VS2019编译器 我们可以看到, main 函数调用之前,是由 invoke_main 函数来调用main函数。...函数栈帧的销毁下 00BE177F pop edi //在栈顶弹出一个值,存放到edi中,esp+4 00BE1780 pop esi //在栈顶弹出一个值,存放到esi中,esp+4 00BE1781
这种数据结构称为栈。栈是一种简单的数据结构,之前学函数的时候我们一直在使用它,却没有意识到!...一、概述 函数栈帧是在内存中的栈区为被调函数开辟的一块空间,里面用来存放该函数中定义的变量等东西,当函数运行完毕栈帧将被销毁。...Push(入栈):为栈增加一个元素 Pop (出栈): 从栈中取出一个元素 二、寄存器 寄存器是中央处理器内用来暂存指令、数据和地址的电脑存储器。寄存器的存贮容量有限,读写速度非常快。...adress) 加载有效地址(在示例中理解) 四、函数栈帧的创建 所有函数的调用都会在内存里面的栈区创建函数栈帧,包括main函数。...ptr [ebp-8],eax //把eax里面的值存到ebp-8这个地址里面(变量z的地址) return z; mov eax,dword ptr [ebp-8] 五、函数栈帧的销毁
函数栈帧的创建和销毁在所有编译器中都是大同小异的,不同的编译器会有不同的方式,但是了解到了简单的底层的这些方法后,其他的编译器都是在此基础上修饰,不必深究。...,一般是由高地址向低地址使用,main函数的使用也要开辟栈帧 esp存入函数低位置的地址,叫做栈顶指针,ebp存入函数高位置的地址,叫做栈底指针。...形参是实参的一份临时拷贝(中肯的一针见血的) 这里我们会有一个疑问,为什么return z 之后这个函数不是销毁了吗?那值不是也会随之销毁吗?...其实这里看到return z 后面的这个汇编指令,它把z的值(z的地址就是ebp-8)赋值给了eax,销毁之后再把eax的值传出去 三个pop将他们逐出去了 它们就被回收了 然后把ebp赋值给...到现在,我把函数栈帧的创建和销毁的过程大致梳理了一遍,我在学完之后有一种恍然大悟的感觉,希望这篇能够帮到大家。
AMS的TaskRecord栈释放机制 如果GC的时候,APP的Java内存使用超过了3/4,就会触发AMS的releaseSomeActivities,尝试回收界面,增加可用内存,但是并非所有场景都会真的销毁...Activity,比如单栈的APP就不会销毁,多栈的也要分场景,可能选择性销毁不可见Activity。...3/4的时候,就会看到前一个TaskRecord栈内Activity被销毁的Log,同时如果通过studio的layoutinspect查看,会发现APP只保留了新栈内的Activity,验证了之前的分析...image.png 总结 单栈的进程,Activity跟进程声明周期一致 多栈的,只有不可见栈的Activity可能被销毁(Java内存超过3/4,不可见) 该回收机制利用了Java虚拟机的gc机finalize...作者:看书的小蜗牛 Android可见APP的不可见任务栈(TaskRecord)被销毁分析 仅供参考,欢迎指正
注:本文章所使用的编译器是VS2010,由于不同编译器的函数栈帧与销毁略有差异,所以具体细节请读者自行实践!...通常我们又称 ebp 为栈底指针,称 esp 为栈顶指针 基本的汇编语言知识 push:压栈 pop:出栈 mov:若有变量a,b,则把b的值赋给a ret:返回主程序 call:调用子程序...mov:赋值和sub:减法 第一步把ebp放到了栈顶,然后在压栈同时esp会自动向上追踪栈顶,所以esp向上移动一个,第二步是将esp赋给ebp,所以ebp指针指向栈顶,第三步是esp指针的地址减少0E4h...也就是刚才传参过来的x,放到eax里,然后把ebp+12就是形参y与eax相加,最后把eax放到ebp-8也就是z的位置: 最后看这个: 首先ebp-8也就是z放到eax,这样子就防止销毁...接下来程序运行完后就是main函数的销毁,与之前Add函数销毁步骤大致相同,就不再赘述了。 关于栈帧创建与销毁的问答题
二、理解函数栈帧能解决什么问题呢? 函数栈帧的创建和销毁,是函数调用的底层逻辑,通过学习这方面的内容可以解决以下问题: 1、局部变量是如何创建的? 2、为什么局部变量不初始化内容是随机的?...三、函数栈帧的创建和销毁 3.1 什么是栈?...3.5.5.6Add函数的栈帧销毁 此图为Add函数的栈帧销毁 pop edi 在栈顶弹出一个值,存放到edi中,esp+4 pop esi 在栈顶弹出一个值...main函数的ebp地址,这样当Add函数调用完成销毁的过程中,栈顶弹出栈的时候就可以将main函数的ebp弹出来并将Add函数的ebp更新为main函数的ebp。...对形参进行及时的销毁。 五、对 二 中的问题进行解释 通过对函数栈帧的创建和销毁学习后,对于这个函数的底层知识有了更深刻的理解。以此们可以解决目录二中提到的问题。
二、理解函数栈帧能解决什么问题呢? 只要理解了函数栈帧的创建和销毁,以下问题就能够很好的理解了: 1、局部变量是如何创建的? 2、为什么局部变量不初始化内容是随机的?...三、函数栈帧的创建和销毁解析 1、什么是栈?...2、这块空间的维护是使用了2个寄存器: esp 和 ebp , ebp 记录的是栈底的地址, esp 记录的是栈顶的地址。 3、函数栈帧的创建和销毁过程,在不同的编译器上实现的方法大同小异。...3.5、函数栈帧的销毁 当函数调用要结束返回的时候,前面创建的函数栈帧也开始销毁。 那具体是怎么销毁的呢?我们看一下反汇编代码。...到这里我们给大家完整的演示了main函数栈帧的创建,Add函数站真的额创建和销毁的过程,相信大家已经能够基本理解函数的调用过程,函数传参的方式,也能够回答课件开始处的问题了。
目录 什么是栈帧 什么是栈 栈帧的创建与销毁 main函数调用过程 Add函数的调用过程 ---- 什么是栈帧 简单地说 程序的执行过程可看作连续的函数调用,而C语言中,每个栈帧对应着一个未运行完的函数...共同维护函数栈帧 ---- 栈帧的创建与销毁 在VS2013下逐步调试add函数向大家展示并讲解栈帧的创建和销毁过程 int Add(int x, int y) { int z = 0;...ecx又开辟了一开新空间,用于存放call指令下一条指令的地址,便于返回 ---- Add函数的调用过程 汇编代码 栈帧创建和销毁过程 ---- mov(赋值)将[ebp + 8]地址的内容赋值给...指令,将edi, esi,ebx寄存器退出栈顶 并用mov(赋值)命令将ebp寄存器中的地址赋值给esp(ebp,esp是维护空间边界的两个寄存器,当他俩地址相遇时,代表这片空间消失)相当于将为Add函数开辟的空间销毁...再出栈ebp就回到了main函数的栈底 ---- ret(返回)返回存放在当前栈顶的地址中的地址值,即回到了刚才Call(声明返回地址)指令的下一条指令处(即把形参也弹出去了) ---- add函数栈帧的创建和销毁就已经完成了
那关于这些问题,如果我们了解了函数栈帧的创建和销毁,就会豁然开朗。 那接下来,我们就来一起学习一下函数栈帧的创建和销毁的过程… 3. 函数栈帧的创建和销毁解析 3.1 什么是栈?...函数栈帧的创建和销毁过程,在不同的编译器上实现的方法大同小异,本次演示以VS2022(Debug下X_86环境)为例。...因为: z是一个创建在Add函数栈帧上的局部变量啊,Add函数调用结束,栈帧销毁,我们还找得到z吗? 找不到了。...那再往下,是printf函数的调用,接着就是main函数栈帧的销毁,那它们和Add函数的调用以及栈帧的销毁是差不多的,我就不过多赘述了。...到这里我们给大家完整的演示了main函数栈帧的创建,Add函数栈帧的创建和销毁的过程,相信大家已经能够基本理解函数的调用过程,函数传参的方式。
导言 本篇内容为函数的补充知识点——函数栈帧的创建和销毁。 在本篇内容中,我们将会学习在函数篇章中未提到的一些知识点: 局部变量是如何创建的?...今天介绍的环境是VS2019,如果有朋友电脑上有安装VS2013、VS2010甚至是VC6.0的话,能够更加容易学习和观察函数栈帧的创建与销毁这一过程。...注:今天我们研究的函数栈帧的创建与销毁就与BP和SP这两个寄存器密切相关。 寄存器SI和DI称为变址寄存器,通常与DS一起使用,为访问现行数据段提供段内地址偏移量。...以上就是函数栈帧销毁的整个过程,通过pop、ret指令来释放函数栈帧的空间。现在已经回到主函数了,我们还有一个问题没有解决,Add函数的值是如何返回到main函数中的?...那到目前为止,函数栈帧的创建与销毁过程我就全部介绍完了,后面还有涉及到printf函数的调用与main函数的函数栈帧的销毁我就不过多叙述了。如果各位还有何疑问的话可以在评论区留言哦!
目录 1、本节目标 2、相关寄存器 3、相关汇编指令 4、什么是函数栈帧 5、什么是调用堆栈 6、函数栈帧的创建和销毁 (1)、main函数栈帧的创建与初始化 (2)、main函数的核心代码 (3)、...函数是怎样在栈区上开辟和释放空间的? 想要对上面的这六个问题做出准确深入的回答,我们需要学习函数栈帧的创建和销毁相关知识,在正式进入函数栈帧之前,我们需要了解一些相关的寄存器和汇编指令。...---- 6、函数栈帧的创建和销毁 我们以一段程序为例讲解函数栈帧:(注意: 函数栈帧的创建和销毁过程,在不同的编译器上实现的方法和细节会有所差异,一般来说,越新的编译器对函数栈帧的封装就越严密,本次演示以...(4)、Add函数栈帧的销毁 当函数调用要结束返回的时候,前面创建的函数栈帧也开始销毁,具体销毁过程如下: ---- (5)、调用完成 调用完Add函数,回到main函数的时候,继续往下执行,可以看到...函数是怎样在栈区上开辟和释放空间的? 函数通过改变esp和edp的指向来创建和销毁空间 (即形成函数栈帧),空间销毁并不会清除该空间中的数据,下一次使用该空间时新数据直接覆盖原数据即可。 ----
各种栈的内存位置? 介绍完栈的工作原理和用途作用后,我们回归到 Linux 内核上来。...Linux 内核将这 4G 字节的空间分为两部分,将最高的 1G 字节(0xC0000000-0xFFFFFFFF)供内核使用,称为 内核空间。...进程栈的初始化大小是由编译器和链接器计算出来的,但是栈的实时大小并不是固定的,Linux 内核会根据入栈情况对栈区进行动态增长(其实也就是添加新的页表)。...二、线程栈 从 Linux 内核的角度来说,其实它并没有线程的概念。Linux 把所有线程都当做进程来实现,它将线程和进程不加区分的统一到了 task_struct 中。...线程仅仅被视为一个与其他进程共享某些资源的进程,而是否共享地址空间几乎是进程和 Linux 中所谓线程的唯一区别。
领取专属 10元无门槛券
手把手带您无忧上云