push bp的作用是什么

谁在墙外等红杏
企业官方账号
博客专家认证
2009-01-08 08:01:07
以下是这个函数的汇编代码
int add(int x, int y){return x+y;};
有几点不明白,在以下的注释中

push ebp ;缓存栈基址,为什么要缓存栈基址?
mov ebp, esp ;为什么要将目前栈顶作为栈基址?
mov eax, dword ptr [ebp+C] ;
add eax, dword ptr [ebp+8] ;
pop ebp ;为什么要恢复栈基址?
retn ;返回
...全文
1775 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
綄羙谎唁 2012-01-14
  • 打赏
  • 举报
回复
“这条语句是为了保护ebp因为在函数中要使用ebp来取得主程序传来的实参
说白了这段代码就是典型的参数传递问题:是通过堆栈来实现的

push ebp ;因为子程序中要使用栈基址寄存器ebp

那么ebp中在主程序中保存的是什么呀????
aguo2006 2009-04-15
  • 打赏
  • 举报
回复
学习了,
ldfqq 2009-01-10
  • 打赏
  • 举报
回复
不同的语言不相同,举个例子吧:
象VS2008的main反汇编后,代码如下

int main()
{
return 0;
}


反汇编生成的汇编代码:
2 00411370 55 push ebp ;保存ebp指针
2 00411371 8bec mov ebp,esp ;将esp赋值给ebp,使ebp指向栈顶
2 00411373 81ecc0000000 sub esp,0C0h ;在堆栈中留出0ch字节的空间给局部变量使用
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 ldfqq 的回复:]
也要预留
[/Quote]
多少个字节.这要样的话是否可以越程序域访问数据了,就是说可以访问别的程序的数据.
kexin_online 2009-01-10
  • 打赏
  • 举报
回复
学习~
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 xiaopoy 的回复:]
访问的是其他函数的
当然访问之后程序依然可正常执行才是最重要的
[/Quote]
是指哪些的其它函数?
是指本程序的,还是指其它程序的.
如果是其它程序的函数或者数据那么我的推测就达成了.
xiaopoy 2009-01-10
  • 打赏
  • 举报
回复
访问的是其他函数的
当然访问之后程序依然可正常执行才是最重要的
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 ldfqq 的回复:]
不同的语言不相同,举个例子吧:
象VS2008的main反汇编后,代码如下

C# code
int main()
{
return 0;
}




Assembly code
反汇编生成的汇编代码:
2 00411370 55 push ebp ;保存ebp指针
2 00411371 8bec mov ebp,esp ;将esp赋值给ebp,使ebp指向栈顶
2 00411373 81ecc0000000 sub esp,0C0h ;在堆栈中留出0ch字节的空间给局部变量使用
[/Quote]
这样的话我不是可以用溢出手段访问其它程序的数据了
int main()
{
int buf[1];
buf[ebp+x]=anyone; //这么说buf[ebp+x]是其它程序的数据了.
return 0;
}
cnzdgs 2009-01-10
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 ioriliao 的回复:]
如果没有命令行参数也没有其它变量呢?
[/Quote]
那就不需要了,只是有些高级语言编译器会自动生成这些代码。
cnzdgs 2009-01-09
  • 打赏
  • 举报
回复
上面写错了一点,sub ebp, xxx应该是sub esp, xxx,其目的是为局部变量分配空间,xxx表示该函数内存所有局部变量所需的总空间(字节数)。
cnzdgs 2009-01-09
  • 打赏
  • 举报
回复
函数的参数和局部变量都是在栈中分配的,ebp寄存器就是为了方便访问栈中的数据而设计的,通常的函数开头都会执行
push ebp
mov ebp, esp
sub ebp, xxx
这样的代码,之后[ebp]是原ebp的值,[ebp+4]是返回地址,[ebp+8]开始向后是函数的各个参数,[ebp-4]开始向前是局部变量。
函数返回前会执行
mov esp, ebp
pop ebp
push和pop的目的是保护ebp的原值不被破坏。
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 erigido 的回复:]
顶!

栈结构(参数入栈顺序跟调用方式有关,这里以C语言默认的CDECL为例):

+| (栈底方向,高位地址) |
| ....................|
| ....................|
| 参数3 |
| 参数2 |
| 参数1 |
| 返回地址 |
-| 上一层[EBP] |
| 局部变量1 |
| 局部变量2 |
|.....................|

补充:栈一直随着函数调…
[/Quote]

谢谢...明白了,不过还有一点.
就是把main函数反汇编时也是一样的先.push ebp mov ebp, esp
如果此时 add ebp 会访问到什么样的数据呢?这样是否是跨越程序段访问数据了?
ldfqq 2009-01-09
  • 打赏
  • 举报
回复
也要预留
RockurSoul 2009-01-09
  • 打赏
  • 举报
回复 2

push ebp ;这是保存栈的基地址,因为被调用程序要利用当前栈的相对位置来访问栈内数据
;当然你也可以不这么做,试想一下你如何获得当前esp+c处的数据,(每次push的时候,esp都是变化的)
mov ebp, esp ;仔细看上面
mov eax, dword ptr [ebp+C] ;取得y的值,一般入栈顺序使自右往左
add eax, dword ptr [ebp+8] ;取得x的值
pop ebp ;为什么要恢复栈基址?修改了栈的基地址后,却要返回,但调用程序的栈可能还会用其他有用的数据,不能被破坏
retn ;维持栈平衡,执行这句后,esp指向了x,y入栈前的栈位置
erigido 2009-01-09
  • 打赏
  • 举报
回复
顶!

栈结构(参数入栈顺序跟调用方式有关,这里以C语言默认的CDECL为例):

+| (栈底方向,高位地址) |
| ....................|
| ....................|
| 参数3 |
| 参数2 |
| 参数1 |
| 返回地址 |
-| 上一层[EBP] |
| 局部变量1 |
| 局部变量2 |
|.....................|

补充:栈一直随着函数调用的深入,一直想栈顶方向压下去。每次调用函数时候,先压函数参数(从右往左顺序压),再压入函数调用下条指令的地址(由call完成)。接着进入调用函数体中先执行PUSH EBP; MOV EBP ESP;(一般已经由编译器加入到函数头中了),接着就是吧函数体中的局部变量压入栈中。再遇到函数的调用的嵌套则依此类推。(added by smsong)

“PUSH EBP”“MOV EBP ESP”这两条指令实在大有深意:首先将EBP入栈,然后将栈顶指针ESP赋值给EBP。“MOV EBP ESP”这条指令表面上看是用ESP把EBP原来的值覆盖了,其实不然——因为给EBP赋值之前,原EBP值已被压栈(位于栈顶),而新的EBP又恰恰指向栈顶。
此时EBP寄存器就已处于一个很重要的地位,该寄存器中存储着栈中的一个地址(原EBP入栈后的栈顶),从该地址为基准,向上(栈底方向)能获取返回地址、参数值,向下(栈顶方向)能获取函数局部变量值,而该地址处又存储着上一层函数调用时的EBP值!
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 ldfqq 的回复:]
谢谢...明白了,不过还有一点.
就是把main函数反汇编时也是一样的先.push ebp mov ebp, esp
如果此时 add ebp 会访问到什么样的数据呢?这样是否是跨越程序段访问数据了?

此时是否[ebp+X],要看是否有实参要取出,即是否有main(命令行参数列表)
如果没有参数列表,也要在堆栈中留出一定字节的空间给局部变量使用,
[/Quote]
如果没有命令行参数也没有其它变量呢?
ldfqq 2009-01-09
  • 打赏
  • 举报
回复
谢谢...明白了,不过还有一点.
就是把main函数反汇编时也是一样的先.push ebp mov ebp, esp
如果此时 add ebp 会访问到什么样的数据呢?这样是否是跨越程序段访问数据了?

此时是否[ebp+X],要看是否有实参要取出,即是否有main(命令行参数列表)
如果没有参数列表,也要在堆栈中留出一定字节的空间给局部变量使用,
elmnd 2009-01-09
  • 打赏
  • 举报
回复
调用函数的过程就是入栈和出栈啊~
okmnji79513 2009-01-09
  • 打赏
  • 举报
回复
正好 遇到类似问题,学习下
cnzdgs 2009-01-09
  • 打赏
  • 举报
回复
这要看具体情况了,总之不要随便改ebp就是了。
加载更多回复(3)

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧