二、常用寄存器及简单汇编指令 寄存器 用途 EAX 累加寄存器:用于乘除法、函数返回值 EBX 用于存放内存数据指针 ECX 计数器 EDX 用于乘除法、IO指针 ESI 源索引寄存器,存放源字符串指针...EDI 目标索引寄存器,存放目标字符串指针 ESP 存放栈顶指针 EBP 存放栈底指针 汇编指令 用途 mov mov A,B 将数据B移动到A push 压栈 pop 出栈 call 函数调用 add...在调试过程中将转到反汇编,便能直观的看到main函数栈帧创建的过程。首先需明确的是,函数栈帧由寄存器esp,ebp维护。...2.esp值传递给ebp。 3.esp减去0E4h:由于栈先使用高地址后使用低地址,减去一个值意味着esp指针向低地址移动了0E4h个地址,此处便开辟了main函数的栈帧。...eax,此时的ebp存放Add函数的栈底指针,(ebp + 8) 的位置即函数传参时创建的ecx的地址,其内部存放的正是10。
通用寄存器通用性强,对任何指令,它们具有相同的功能。为了缩短指令代码的长度,在8086中,某些通用寄存器用作专门用途。...二、函数栈帧的创建 函数栈帧的创建与维护是通过 bp 和 sp 这两个寄存器实现的,在汇编语言中,这两个寄存器被称为 ebp 和 esp 。...这两个寄存器存放的是地址,所以ebp又被称为栈底指针,esp又被称为栈顶指针。...*[bp]: 基址指针寄存器 *[sp]: 堆栈指针寄存器 *[ebp]: 栈底指针 *[esp]: 栈顶指针 接下来我们就通过下面这个代码来介绍一下 ebp 和 esp 它们是如何创建和维护函数栈帧的...那我们就能得到一块由 esp 和 ebp 所指向的新空间: 这块新指向的空间是什么呢?别着急,我们接着往下看。
然后下面我们来介绍一下常用的一些寄存器: 除 EBP 和 ESP 外,其他几个寄存器的用途其实是比较任意的,也就是什么都可以存。...ebp 和 esp也被称为栈基指针和栈顶指针,它们两个是用来维护函数的栈帧。 那它是如何来维护的呢?...对 x86 体系的 CPU 而言,寄存器 ebp 可称为栈基(栈底)指针(base pointer),寄存器 esp可称为栈顶指针(stack pointer) 而ebp 和 esp就是维护函数栈帧的...: 然后再往下 pop ebp,弹出栈顶的值给ebp,此时栈顶放到是什么?...所以,前面我们为什么要main函数的ebp栈基指针push存起来,其实就是为了函数调用结束回来的时候我们能获取到原来main函数对应的栈基指针的值,从而使ebp重新指向main函数的栈底,维护main函数的栈帧
然后根据保存的ebp,和下一指令的地址找到新的函数,即要执行的指令的地址。 不同的函数会开辟不同的空间。 1.ebp,esp两个寄存器用来维护函数栈帧 1.ebp寄存器:栈底寄存器。...2.esp寄存器:栈顶寄存器。 3.pc指针寄存器:也叫程序计数器,它永远指向当前指令的下一条指令。...ebp寄存器就用来维护main函数的函数栈帧。...当进入Add函数,去运行Add函数的时候,esp和ebp就去维护Add函数的函数栈帧,并且把mian函数的esp和ebp的指针保存下来,等Add函数结束以后,esp和ebp就又可以去维护main函数的函数栈帧...3.函数栈帧创建的过程 在调用main函数时,已经存在来到下面情形,__tmainCRTStartup()调用main函数 1.push ebp:在栈顶,在栈顶把ebp指针的值放进去。
有:eax ebx ecx edx ebp esp ebp与esp这两个寄存器中存放的是地址,这两个地址是用来维护函数栈帧的。...首先,创建一个_tmainCRTStartup函数栈帧,我们假设栈区下面为高地址,上面为地地址。 esp为栈顶指针,ebp为栈底指针 这样我们就可以进入,我们通过汇编代码可以看出第一步为push。...函数栈帧与那main一样 先push ebp将main函数栈底指针地址通过这个元素储存起来方便返回时能找到main函数栈底指针 再move,sub将esp和ebp定义新的位置,再push三个元素ebx,...esi,edi,最后再将Add函数栈帧初始化“CCCCCCCCC” 接着给z创建空间,ebp-8的位置 然后就是将传过去的b和a加起来储存在eax寄存器里面 接着将eax里面的值移动到z空间里(ebp-...函数是怎么传参的,函数传参的顺序是什么 我们通过push将两个实参压栈,从而栈顶有了两个独立空间,将两个值放进去,创建好调用的函数栈帧后,通过指针的偏移量,实现传参。
EBP保存了调用函数时的堆栈顶部地址,通过维持这个固定的堆栈框架,可以方便地通过相对偏移访问不同的局部变量。 3.栈顶指针(ESP):ESP寄存器用于跟踪和管理堆栈的当前顶部地址。...当Add函数被调用时,编译器会执行以下步骤来创建函数栈帧: 1. 首先,编译器将函数的返回地址和旧的栈帧指针(EBP)保存在栈上。 2....接下来,编译器会在栈帧中初始化一部分空间,即栈顶指针(ESP)和栈低指针(EBP)之间的空间,并为函数的局部变量和参数在栈帧中分配存储空间。未初始化的局部变量会包含随机值。...调整栈顶指针 紧接着,通过执行 MOV 指令,让栈顶指针(ESP)指向 EBP 原先的指向位置。这样做的目的是为了释放函数栈帧所占用的内存空间。 3....当调用函数时,在调用之前,用push把参数从右向左压栈, 当进入形参函数时,在函数的栈桢里通过指针偏移量找到形参 4.形参和实参是什么关系?
分为标志寄存器FR,指令指针寄存器IP,段寄存器,指针和变址寄存器,通用寄存器组等…… >我们今天所讲到的都是通用寄存器 寄存器名称 功能 eax 累加寄存器,相对于其他寄存器,在进行运算方面比较常用...当然, ESI也可以被装入任意的数值, 但通常没有人把它当作通用寄存器来用。 esp 为扩展基址指针寄存器,也被称为帧指针寄存器,用于存放函数栈底指针。...它会随着我们栈空间的大小变化,从而改变其所指地址的位置,以适应栈帧空间的大小变化 ebp 为扩展栈指针寄存器,是指针寄存器的一种,用于存放函数栈顶指针。...,我们将ebp指针地址压栈到了栈帧空间当中,而这个edp其实就是指向main函数栈帧底部的指针,随后我们又进行了调整ebp和esp位置的汇编指令操作,其目的就是重新改变ebp和esp所维护的函数栈帧空间...ret //执行这条指令后我们会直接回到main函数中call指令的下一条指令的位置 注意我们的指令,我们将ebp-8处的值重新放回到eax寄存器当中(这么做的原因是什么呢?
栈帧中维持着函数调用所需要的各种信息,包括函数的入参、函数的局部变量、函数执行完成后下一步要执行的指令地址、寄存器信息等。...栈顶和栈底都有指针,栈顶指针是esp,栈底指针是ebp,即esp指向栈顶,ebp指向栈底。...EBP是"基址指针"(BASE POINTER), 它最经常被用作高级语言函数调用的"框架指针"(frame pointer)。...函数返回时作 mov esp,ebp pop ebp ret 即可。 ESP 专门用作堆栈指针,被形象地称为栈顶指针,堆栈的顶部是地址小的区域,压入堆栈的数据越多,ESP也就越来越小。...它的原理是什么,我们必须从源代码转化的汇编代码着手去了解(汇编语言相较于高级语言,更面向机器,底层逻辑更完善。
函数栈帧的创建与销毁 导语 问题 寄存器 函数栈帧 函数栈帧是什么? 内存分布 什么是栈?...,用于存放目的地址的,和esi两个经常搭配一起使用,执行字符串的复制等操作 今天主要的是: ebp 栈底指针,指向栈的底部,用ebp+偏移量的形式来定位函数存放在栈中的局部变量 esp 栈顶指针...,指向栈的顶部 这两个寄存器用来存放地址用来维护函数栈帧 函数栈帧 函数栈帧是什么?...第二行的指令是什么意思呢? 把esp的值给ebp(注意,esp和ebp为指针,它们里面储存的是地址) 也就是说ebp不会指向原来的位置了,和esp指向相同的位置。...在正式说这段代码我要说一句,现在维护代码的两个寄存器已经移动很多次了,也就是说现在main函数的栈帧已经这么大了: 我们再看现在需要的指令:让我们把ebp进行压栈,这里的ebp其实是main函数的
某个时刻,只有位于栈顶的栈帧可用,它代表了某个方法正在执行中的各种状态。最顶端的栈帧用两个指针界定,栈指针,帧指针。他们对应于栈中的地址分别存储在寄存器 %ebp 和 %esp 中。...栈中的大致结构如下: [image] 栈指针始终指向栈顶元素,控制着栈中元素的出入栈,帧指针指向的是当前栈帧的底部,注意是当前栈帧,不是整个栈的底部。...subl 指令将寄存器 %esp 中的地址减去 20,即栈指针向上扩展了 20 个字节(栈是倒着生长的),也就是为当前栈帧分配了 20 个字节大小。...接着,movl 将值 20 写入地址 -4(%ebp),这个地址其实就是相对寄存器 %ebp 帧指针位置之上的四个字节处。...然后跳向了 sayHello 方法的第一条指令开始执行,pushl 将寄存器 %ebp 中的地址压栈,这时候的 %ebp 是上一个栈帧的帧指针地址,这个操作其实是一个保存的动作。
某个时刻,只有位于栈顶的栈帧可用,它代表了某个方法正在执行中的各种状态。最顶端的栈帧用两个指针界定,栈指针,帧指针。他们对应于栈中的地址分别存储在寄存器 %ebp 和 %esp 中。...栈中的大致结构如下: ? 栈指针始终指向栈顶元素,控制着栈中元素的出入栈,帧指针指向的是当前栈帧的底部,注意是当前栈帧,不是整个栈的底部。...subl 指令将寄存器 %esp 中的地址减去 20,即栈指针向上扩展了 20 个字节(栈是倒着生长的),也就是为当前栈帧分配了 20 个字节大小。...接着,movl 将值 20 写入地址 -4(%ebp),这个地址其实就是相对寄存器 %ebp 帧指针位置之上的四个字节处。...然后跳向了 sayHello 方法的第一条指令开始执行,pushl 将寄存器 %ebp 中的地址压栈,这时候的 %ebp 是上一个栈帧的帧指针地址,这个操作其实是一个保存的动作。
所以任何函数调用进来的第一件事都是保护调用者的帧指针,以使得返回时可以恢复调用者的帧指针,即pushl %ebp movl %esp %ebp有了上面这两个命令,函数就可返回了,返回时只要leave...寄存器%ebp通常用做帧指针(frame pointer),而esp则用作栈指针(stack pointer)。...可以看出,函数swap()从调用者main()的栈帧中获取其参数。图中的位置信息相对于寄存器ebp中的帧指针。栈帧左边的数字指出了相对于帧指针的地址偏移值。...)的地址传送给寄存器%eax,此时 帧指针esp指向了-12%ebp处)25 pushl %eax # 作为调用的参数并压入栈中。...popl %ebp # 恢复原ebp的值(通常是调用者的帧指针)。这部分代码恢复了在进入swap()函数时寄存器esp和ebp的原有值,并执行返回指令ret。
在前期的学习中,我们可能会有很多困惑: 局部变量是怎么创建的? 为什么局部变量的值是随机值? 函数是怎么传参的?传参的顺序是怎样的? 形参和实参是什么关系? 函数调用是怎么做的?...函数调用结束后是怎么返回的? 那么通过学习函数栈帧的创建和销毁,以上困惑就会迎刃而解。...为了讲清楚函数栈帧,我们需要先做一些铺垫: 寄存器: eax ebx ecx edx ebp esp ebp、esp这2个寄存器中存放的是地址,这2个地址是用来维护函数栈帧的...总结: 局部变量在函数的栈帧里被分配了一些空间进行创建 局部变量不初始化的时候是随机值(比如上述过程中不初始化之前是cccccccc) 函数在调用之前就把参数从右向左进行压栈;真正进入函数后通过指针的偏移量找到形参...形参是实参的一份临时拷贝,改变形参不会影响实参 通过寄存器把返回值带回来
ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶,即栈顶寄存器。...EBP:基址指针寄存器(extended base pointer),即栈底寄存器。...寄存器指示它自己的栈帧。...EBP寄存器现在正指向main的栈帧中的某个位置,这个值必须被保留,因此,EBP进栈。然后ESP的内容赋值给了 EBP。...这其中也许有进栈、出栈的动作,栈指针ESP也会上下移动,但EBP是保持不变的。这意味着我们可以一直用[EBP+…]找到第一个参数,而不管在函数中有多少进出栈的动作。
,我们使用的编译器版本越高,越不容易观察找这个函数栈帧的过程,我们这里使用的是vs2013为例: 1.关于寄存器你应该知道的 我们之前学习的时候了解过,这个寄存器有eax,ebx,ecx,edx等等,我们在学习函数栈帧的时候...,经常使用的两个寄存器就是ebp和esp,这两个寄存器存放的是地址,存放的这两个地址用来维护函数的栈帧; 2.函数栈帧的初步理解 每一个函数的调用,都要在栈区开辟空间,在栈区里面,我们会优先使用高地址,...,我们就会从低向高处盖房子,我们的ebp指针也被称为栈底指针,esp也被称为栈顶指针,我们现在维护的是main函数的函数栈帧,当调用其他的函数的时候,这两个指针就会维护其他的函数的栈帧空间; 我们还需要了解的就是...我们这里是把esp的值给ebp,我们的ebp原来是指向栈的底部的(不是下面的图片,下面的图片展示的是最后的结果),就是我们的ebp不是压栈了吗,每次进行压栈,我们的esp都要进行移动,因为esp是栈顶指针...)return z指令的后面的ebp-8实际上就是我们的计算结果30,我们把这个数据存到eax这个寄存器里面,这个寄存器是不会随着add函数栈帧的销毁而消失的; (2)返回之后的指令是,pop就是我们前面已经铺垫的出栈的操作
[pop 寄存器] 功能:出栈,以一个寄存器接受出栈的数据。包含两个动作:将栈中的数据保存在寄存器中,同时栈顶指针向下(高地址)偏移。...2.使得esp和ebp指向同一块内存区域,虽然esp和ebp是寄存器,但由于其内保存的是地址,所以在此我们也可以形象的将esp和ebp看做指针,便于理解。...同时栈顶指针向上偏移(低地址)。 2.将[ebp-4]指向内存块中的值存入寄存器ecx中,并进行压栈。同时栈顶指针向上偏移(低地址)。...但是值得注意的是栈帧开辟的时候进行push ebp的操作。...2.0040104E mov esp,ebp使得被调用函数栈帧回退。此时栈帧空间的内容还存在。 3.pop ebp 两个动作,出栈,并将出栈的值赋给ebp。
在x86环境中,esp和ebp是两个特殊的寄存器,用于管理栈帧和函数调用。 esp寄存器(Extended Stack Pointer)是栈指针寄存器,用于指向栈的顶部。...ebp寄存器(Extended Base Pointer)是基址指针寄存器,也称为帧指针寄存器。它通常用于指向当前函数的栈帧的底部。栈帧是一个用于存储函数的局部变量和其他相关信息的区域。...在函数调用过程中,通常会按照以下步骤使用esp和ebp寄存器: 在函数的入口处,通过将当前的ebp值保存到栈上,创建一个新的栈帧。这样可以在函数执行期间保存上一级函数的栈帧信息。...将当前的esp值赋给ebp寄存器,以建立当前函数的栈帧。这样可以使用ebp作为基址指针来访问函数的局部变量和其他相关信息。...指针寄存器(Pointer Registers): ESP (Stack Pointer Register):指向栈的顶部,用于管理函数调用时的栈帧。
5)视频流中的PTS和DTS又是什么?什么是I帧、P帧、B帧?I帧:intra picture,帧内编码帧。...P帧表示的是这一帧跟之前的帧的差别,P帧可以作为后续图像编码时的参考帧。解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。...I帧或P帧;4)P帧可以是其后面P帧的参考帧,也可以是其前后的B帧的参考帧;5)由于是差值传送,P帧的压缩比较高。...IDR帧也是I帧的一种,那么IDR帧与普通I帧有何区别呢?一个IDR帧之后的所有帧都不能引用该 IDR 帧之前的帧的内容;而对于普通的I帧,其后的P帧和B帧可以引用该普通I帧之前的其他I帧。...视频流中的DTS和PTS又是什么?DTS主要用于视频的解码,全称是Decoding Time Stamp, 为解码时间戳。
EBP相当于一个“基准指针”。从main传递到foo的参数以及foo本身的局部变量都可以通过这个基准指针为参考,加上偏移量找到。...在函数调用前,main正在用ESP和EBP寄存器指示它自己的栈帧。 首先,main把EAX,ECX和EDX压栈。这是一个可选的步骤,只在这三个寄存器内容需要保留的时候执行此步骤。...指令调用子函数: call foo 当call指令执行的时候,EIP指令指针寄存器的内容被压入栈中。...首先foo必须建立它自己的栈帧。EBP寄存器现在正指向main的栈帧中的某个位置,这个值必须被保留,因此,EBP进栈。然后ESP的内容赋值给了EBP。...这个动作之后,栈顶就回到了我们开始整个函数调用过程前的位置,也就是图5中粗线的位置。 看个具体的实例: 这段代码反汇编后,代码是什么呢?
待解决疑惑: 局部变量是怎么创建的? 为什么局部变量的值是随机值? 函数是怎么传参的?传参的顺序是怎样的? 形参和实参是什么关系? 函数调用是怎么做的?...函数调用是结束后怎么返回的? 1.寄存器 寄存器是计算机中的一种内部存储器件。它是位于CPU内部的一组存储单元,用于暂时存储指令执行过程中的数据,如算术运算的操作数、地址等。...寄存器的容量很小,通常只有几十个字节,但它的数据传输速度非常快,因此能够快速地完成指令的执行。寄存器的种类有很多,如通用寄存器、指令指针寄存器、程序计数器寄存器等。...C语言的寄存器包括:eax , ebx , ecx , edx , ebp , esp 函数栈帧 ebp ,esp 这两个寄存器中存放的是地址,这两个地址是用来维护函数栈帧的....若对调试步骤有疑惑可以点击:http://t.csdnimg.cn/nQiJn 学习开始 首先,为main函数先开辟栈帧空间 根据逐步运行结果可以发现esp地址减小了,说明ebp被压入栈内
领取专属 10元无门槛券
手把手带您无忧上云