1.栈是用来存储临时变量,函数传递的中间结果。
2.操作系统维护的,对于程序员是透明的。
我们可能只强调了它的后进先出的特点,至于栈实现的原理,没怎么讲?下面我们就通过一个小例子说说栈的原理。
先写个小程序:
void fun(void)
printf("hello world");
void main(void)
fun()
printf("函数调用结束");
这是一个再简单不过的函数调用的例子了。
当程序进行函数调用的时候,我们经常说的是先将函数压栈,当函数调用结束后,再出栈。这一切的工作都是系统帮我们自动完成的。
但在完成的过程中,系统会用到下面三种寄存器:
1.EIP
2.ESP
3.EBP
当调用fun函数开始时,三者的作用。
1.EIP寄存器里存储的是CPU下次要执行的指令的地址。
也就是调用完fun函数后,让CPU知道应该执行main函数中的printf("函数调用结束")语句了。
2.EBP寄存器里存储的是是栈的栈底指针,通常叫栈基址,这个是一开始进行fun()函数调用之前,由ESP传递给EBP的。(在函数调用前你可以这么理解:ESP存储的是栈顶地址,也是栈底地址。)
3.ESP寄存器里存储的是在调用函数fun()之后,栈的栈顶。并且始终指向栈顶。
当调用fun函数结束后,三者的作用:
1.系统根据EIP寄存器里存储的地址,CPU就能够知道函数调用完,下一步应该做什么,也就是应该执行main函数中的printf(“函数调用结束”)。
2.EBP寄存器存储的是栈底地址,而这个地址是由ESP在函数调用前传递给EBP的。等到调用结束,EBP会把其地址再次传回给ESP。所以ESP又一次指向了函数调用结束后,栈顶的地址。
其实我们对这个只需要知道三个指针是什么就可以,可能对我们以后学习栈溢出的问题以及看栈这方面的书籍有些帮助。当有人再给你说EIP,ESP,EBP的时候,你不能一头雾水,那你水平就显得洼了许多。其实不知道我们照样可以编程,因为我们是C级别的程序员,而不是ASM级别的程序员。
详细解析ESP寄存器与EBP寄存器 最近在看汇编码,经常在程序的开头看到ESP和EBP寄存器的出现,由于本人基础知识的不牢靠,便上网查阅相关的资料,可惜网上的资料都不给力,都只是流于形式,没有...
来自:
南浦
esp是栈指针,是cpu机制决定的,push、pop指令会自动调整esp的值;ebp只是存取某时刻的esp,这个时刻就是进入一个函数内后,cpu会将esp的值赋给ebp,此时就可以通过ebp对栈进行操...
来自:
因热爱而执着,因执着而成功。
原文: http://blog.csdn.net/zsJum/article/details/6117043一直对寄存器ESP和EBP的概念总是有些混淆,查看定义ESP是栈顶指针,EBP是存取堆栈指针...
来自:
Robin Hu的专栏
基本概念:(1)ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。(2)EBP:基址指针寄存器(extended ba...
来自:
yu97271486的成长历程
080483b4: 80483b4: 55 push %ebp 80483b5: 89e5 mov ...
来自:
wzj5530的专栏
一直对寄存器ESP和EBP的概念总是有些混淆,查看定义ESP是栈顶指针,EBP是存取堆栈指针。还是不能很透彻理解。之后借于一段汇编代码,总算是对两者有个比较清晰的理解。下面是按调用约定__stdcal...
来自:
zsJum的专栏
因为对堆栈的操作寄存器有EBP和ESP两个。EBP是堆栈的基址,ESP一直指向栈顶(只要有PUSH动作,ESP就自动减小,栈的生长方向从大往小,不需要手动改变ESP。)所以要压入EBP,然后再用EBP...
来自:
晚晴小筑
#includeintfunc(intparam1,intparam2,intparam3){intvar1=param1;intvar2=param2;intvar3=param3;printf("...
来自:
BAOLIANG196的博客
参考一:EAX、ECX、EDX、EBX寄存器的作用一般寄存器:AX、BX、CX、DXAX:累积暂存器,BX:基底暂存器,CX:计数暂存器,DX:资料暂存器索引暂存器:SI、DISI:来源索引暂存器,D...
来自:
人生代码,代码人生。。。
eax,ebx,ecx,edx,esi,edi,ebp,esp等都是X86汇编语言中CPU上的通用寄存器的名称,是32位的寄存器。如果用C语言来解释,可以把这些寄存器当作变量看待。 比方说:a...
来自:
上善若泪
windows32位汇编的环境下0A10FF61 call 0A11FFAA0A10FF66 MOVEAX,DWORDPTRSS:[EBP+3C]call CALL 地址1 功...
来自:
comeonow的博客
本AI的汇编环境是32位80*86nasm就是这样。先讲下刚刚听那个视频感受,比人类给我讲的要直观些,毕竟是看着跟着汇编代码看olydbg里堆栈区。也不能说讲得多好,就是暂时性让我明白,这个汇编里堆栈...
来自:
努力专业 练习屠龙技
eax,ebx,ecx,edx,esi,edi,ebp,esp等都是X86汇编语言中CPU上的通用寄存器的名称,是32位的寄存器。如果用C语言来解释,可以把这些寄存器当作变量看待。比方说:addeax...
来自:
chenlycly的专栏
可以看到,初始情况下,ebp此时值为0012FEDC,也就是栈帧的地址,而栈顶地址esp值为0012FDFC。可以看到两个值有一定的关系。而帧指针的地址较高。 然后我们让它执行前两句,push...
来自:
u011555996的博客
一.概念分析经常看到下面这两句:pushl%ebpmovl%esp,%ebpesp是堆栈指针 ebp是基址指针 那两条指令的意思是 将栈顶指向 ebp 的地址 ————————————————————...
来自:
无聊的专栏
ebp和esp是32位的SP,BP esp是堆栈指针 ebp是基址指针 ESP与SP的关系就象AX与AL,AH的关系.32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和ED...
来自:
chenlycly的专栏
一.概念分析经常看到下面这两句:pushl%ebp movl%esp,%ebp ------------------------------------------------------------...
来自:
chenglinhust的专栏
moveax,ebx //eax=ebxleaeax,[ebx+30]//eax=ebx+30pushpop //入栈,出栈pushaxpopax//全部入栈,全部出栈addeax,5//eax+=5...
来自:
南的专栏
EBP+C:secondparameterEBP+8:firstparameterEBP+4:returnaddressEBP: previousEBPEBP-4:localvariableEBP-8...
来自:
十八进
函数的工作借助于栈。栈在内存中是一块特殊的存储空间,它的存储原则是“先进后出”,最先被存储的数据最后被释放。esp被称为栈顶指针,ebp称为栈底指针,通过这两个指针寄存器保存当前栈的起始地址与结束地址...
来自:
经典的误导的专栏
ebp:作为函数调用的基址地址,指向函数在栈的起始位置esp:指向当前执行函数的栈顶指针eip:指向下一个将要执行的cpu指令在内存中的位置如果怀疑一个dump为堆栈溢出,可以通过观察这几个指针所指向...
来自:
erikaIT的博客
3、缓冲区溢出之JMPESP本文属于原创,如有错误请指正。其中引用他人的部分已经标出,如涉及版权问题请联系本人这里不得不讲一讲JMPESP的原理了,在实验之前我一直没看懂他是如何试下跳转ESP之后回到...
来自:
大头的博客
正常情况下我们栈的寻址方式是EBP+偏移的方式来寻址的//保留调用前的栈底 PUSHEBP 这里会保留栈底 //提升堆栈 MOVEBP,ESP 我们可以知道这种方式EBP(栈底)寻址...
来自:
随心记
(1)ESP:栈指针寄存器(extendedstackpointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。 由于栈的地址大小是从上到下从大到小,所以ESP指在栈的最底端。(...
来自:
weixin_36627946的博客
首先明白一点:开启一个线程之后,会产生8M的栈空间,在这8M的栈空间中,只要有函数的使用,都会在这8M的基础上开启一个新的栈帧,而不是在开启一个栈 13发生跳转时将跳转指令的下一条指令保存进来也就是l...
来自:
chengchaonan的博客
eax,ebx,ecx,edx,esi,edi,ebp,esp等都是X86汇编语言中CPU上的通用寄存器的名称,是32位的寄存器。如果用C语言来解释,可以把这些寄存器当作变量看待。比方说:addeax...
来自:
gettogetto的博客
首先应该明白,栈是从高地址向低地址延伸的。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(...
来自:
波波诸葛伟
PS:EBP是当前函数的存取指针,即存储或者读取数时的指针基地址;ESP就是当前函数的栈顶指针。每一次发生函数的调用(主函数调用子函数)时,在被调用函数初始时,都会把当前函数(主函数)的EBP压栈,以...
来自:
wangkr的专栏
在linux内核中使用的寄存器。运行时栈由cpu进行控制。使用的是SS、ESPSS:记录的是段选择器,用户程序不可以进程修改。ESP:指向堆栈内部特定位置的32位的指针。//一般用于指向内核栈位置。C...
来自:
码小农
EIP寄存器,用来存储CPU要读取指令的地址,CPU通过EIP寄存器读取即将要执行的指令。每次CPU执行完相应的汇编指令之后,EIP寄存器的值就会增加。 一、因为80386CPU的寻址范围是4GB,所...
来自:
striver1205的专栏
1.EIP2.ESP3.EBP 1.EIP寄存器里存储的是CPU下次要执行的指令的地址。 也就是调用完fun函数后,让CPU知道应该执行main函数中的printf("函数调用结束")语句了。2...
来自:
dadalan的专栏
函数调用是程序设计中的重要环节,本文就函数调用的过程进行分析。一、eip、ebp、esp介绍 EIP,EBP,ESP都是系统的寄存器,里面存储的是些地址,我们系统中栈的实现上离不开他们三个。 我知道栈...
来自:
一小平民
第一 栈首先我们需要了解一下在函数调用时候栈的结构 栈的生长方向由高地址向低地址生长,栈顶指针由sp或者esp确定,当压栈时sp减法操作 每一个函数都是一个栈框架(framestack)。 我们简单...
来自:
hoppboy的专栏
以下是在读《深入理解计算机系统》前面的章节“程序的机器级表示”时,自己动手在linux上使用了gdb对一个简单的C程序进行反汇编,通过不懈的努力终于查清楚弄明白了绝大多数的语句。且均以注释的形式列在汇...
来自:
Windness的技术生活
什么栈帧?从逻辑上讲,栈帧就是一个函数执行的环境:函数参数、函数的局部变量、函数执行完后返回到哪里等等。实现上有硬件方式和软件方式(有些体系不支持硬件栈)首先应该明白,栈是从高地址向低地址延伸的。每个...
来自:
sinat_14840443的专栏
=问题= pushl%ebpmovl%esp,%ebp干嘛要这样? -----------------------------------------------------------------...
来自:
running_noodle的专栏
#includeintfunc(intparam1,intparam2,intparam3){ intvar1=param1; intvar2=param2; intvar3=par...
来自:
fei的专栏
EIP寄存器里存储的是CPU下次要执行的指令的地址。即函数调用完后要执行的地址。EBP寄存器里存储的是栈的栈底指针,通常叫栈基址。这个是在将要进行函数调用时,由ESP传递给EBP的。即函数调用前的ES...
来自:
qq_31202403的博客
修改my.ini文件加上default-character-set=gb2312设定数据库字符集alter database da_name default character set charset...
来自:
血色残阳的专栏
人类之所以进步,在于会使用工具我们知道,有代码比对工具;有版本控制控制工具比对同一个文件不同人修改的地方;还有eclipse工具提供的Compare History 工具;我同事比较“同情”我每次发布...
来自:
skygreen_2001的专栏
网上关于caffe的安装教程非常多,但是关于每一步是否操作成功,出现了什么样的错误又该如何处理没有给出说明。因为大家的操作系统的环境千差万别,按照博客中的教程一步步的安装,最后可能失败——这是很...
来自:
张学志の博客
让我们用Validator框架来给SpringMVC实现验证功能吧
Validator框架源码地址:https://github.com/devefx/validator
完成这一章教程的要求
来自:
devefx的博客
最近好长时间都没有写blog了,主要是因为最近工作上的事以及下载Android源码的事耽误的(下载源码这件事会在后续的blog中写道,这个真的很有意义呀~~),那么今天来写点什么呢?主要的灵感来自于早...
来自:
Android应用安全防护和逆向分析-----作者
QT 创建文件夹 bool QDir::mkdir ( const QString & dirName ) const
创建一个子目录名为目录名。[喝小酒的网摘]http://blog....
来自:
路楷的专栏
本篇文章是根据我的上篇博客,给出的改进版,由于时间有限,仅做了一个简单的优化。相关文章:将excel导入数据库2018年4月1日,新增下载地址链接:点击打开源码下载地址十分抱歉,这个链接地址没有在这篇...
来自:
Lynn_Blog
最近在做一个每天定点从FTP自动下载节目.xml并更新到数据库的功能。首先想到用 FileSystemWatcher来监控下载到某个目录中的文件是否发生改变,如果改变就执行相应的操作,然后用timer...
来自:
kongwei521的专栏
特征空间的隐式映射:核函数
咱们首先给出核函数的来头:在上文中,我们已经了解到了SVM处理线性可分的情况,而对于非线性的情况,SVM 的处理方法是选择一个核函数 κ(⋅,⋅) ,通过将数据映...
来自:
redis的专栏
docx4j官方提供了一些例子,本文只是其中一部分应用的简单例子。需要注意的地方是页眉和页脚,必须创建对应关系才能起作用。页眉和页脚添加图片的时候,第二个参数sourcePart是必须的,调用的cre...
来自:
偶尔记一下
问题背景:
我要在一个表单里同时一次性提交多名乘客的个人信息到SpringMVC,前端HTML和SpringMVC Controller里该如何处理?
第1种方法:表单提交,以字段数组接收;
第2种...
来自:
一个情绪猿的脖克...
一. 密码学简介
据记载,公元前400年,古希腊人发明了置换密码。1881年世界上的第一个电话保密专利出现。在第二次世界大战期间,德国军方启用“恩尼格玛”密码机,密码学在战争中起...
来自:
leolewin的博客
Java中的ThreadLocal类允许我们创建只能被同一个线程读写的变量。因此,如果一段代码含有一个ThreadLocal变量的引用,即使两个线程同时执行这段代码,它们也无法访问到对方的Thread...
来自:
u011860731的专栏
最近买了max系统的笔记本,花了一万多,心疼不行不行的。之前的window 7 的有专门的window 远程连接服务器。Mac怎么办了,微软就开发出来了parallels desktop...
来自:
老程
花了几天,终于把matlab版的人脸检测运行成功了,虽然正确率不是很高,看着各种论文上的人脸检测正确率都出奇的高,我是不怎么相信的,有的论文连基于平均脸的人脸检测正确率都能达到98%,汗啊~~ 也许...
来自:
海海人生
问题场景描述整个项目通过Maven构建,大致结构如下:
核心Spring框架一个module spring-boot-base
service和dao一个module server-core
提供系统...
来自:
开发随笔
最近用软碟通制作了一个win7原版映像,但是在装新系统的时候发现了一个问题,进入安装界面后,显示没有找到驱动器,但是明明是差了U盘的,通过“shift+f12”调出命令行窗口,输入disk list命...
来自:
g_newbie的博客
Settings界面结构简单分析Setting是android系统很重要的模块,这个模块并不是很复杂,这部分也一直在看,很多时候都是在看某个具体的选项,比如WLAN,蓝牙这样具体的源码,但是对于主界面...
来自:
H_Gao的专栏
本文介绍如何使用VS2015作为编译开发环境,调用OpenCV3.31和Qt5.9.1写图像处理的GUI。
1.目录结构
假设我们要创建一个名为VideoZoom的工程,那么首先按下图构建目录结构...
来自:
zhhp1001的博客
上一章只为大家介绍了Validator的后端验证功能,接下来就为大家介绍一下Validator前端功能,你会发现他的巧妙之处。
Validator框架源码地址:https://github.com...
来自:
devefx的博客
Linux下安装mantis配置指...
qq_34889607:
你好,请问你在网页配置mantis连接数据库那一块时有没有遇到过这种报错啊“INTERNAL APPLICATION ERROR”,我之前成功搭建过一次,但是笔记关于网页配置mantis连接数据库那一步没有截图,现在总感觉哪里不对劲。
Oracle中实例(Instanc...
wjp867530559:
我问一下,那一个数据库,多个实例是什么关系?数据库集群是什么概念?为什么要有多个实例对一个数据库?帮忙解释一下,谢谢!很多书上解释不清楚。
软件测试经理是这样炼成的!(连载2)
sun5smile:
看来测试也不是好当的。。。
堆栈中的EIP EBP ESP
sun5smile:
多亏了你,谢谢
Linux下安装mantis配置指...
huangjingxue110:
这个是成功的案例吗