求助--call指令的问题

A8572785 2012-06-15 01:00:37
求解:不是说call指令执行后也会将它下一条指令的地址压入堆栈吗?所以按照下面这个例子,调用的函数参数只有两个啊,所以在恢复堆栈平衡的时候我想应该是add esp,0xc 啊?但是为什么就是add esp,0x8呢?这是为什么呢?
z = Addemup(x,y)
0040101b 8b45f8 mov eax,[ebp-0x8] ; load eax with y
0040101e 50 push eax ; push y on stack
0040101f 8b4dfc mov ecx,[ebp-0x4] ; load ecx with x
00401022 51 push ecx ; push x on stack
00401023 e81b000000 call addemup!Addemup ; call Addemup
00401028 83c408 add esp,0x8 ; fixup stack for args
0040102b 8945f4 mov [ebp-0xc],eax ; z returned in eax
...全文
118 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
e379278011 2012-06-15
  • 打赏
  • 举报
回复
load eax with y ;参数1 4字节
load eax with x ;参数2 ,4字节
返回地址 ; ← esp的位置,esp+4 指向参数2,esp+8指向参数1
一般用ebp作指针,所以接着push ebp,然后mov ebp,esp,那么ebp+0ch指向参数1。
感觉LZ代码没贴全。

建议看80x86汇编语言程序设计教程,杨季文的,第4章,4.2主程序与子程序间的参数传递,研究下。
sxy521 2012-06-15
  • 打赏
  • 举报
回复
对于调用call的情况,原先的CS,ip都是自动入栈的,在返回时,也是通过ret自动出栈的,因为这是每个函数都要执行的,所以封装了,我们在应用时,只需对自己定义的参数进行入栈,出栈即可。当然,在call函数内部,我们还要对函数内部使用的寄存器进行开始保存和最后还原。
zara 2012-06-15
  • 打赏
  • 举报
回复
两个参数,为什么要 add esp, 0x0c 呢?一个参数为一个 dword 是 4 个字节,两个不就是 8 么,怎么会出来个 0x0c ?
gsy999 2012-06-15
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
求解:不是说call指令执行后也会将它下一条指令的地址压入堆栈吗?所以按照下面这个例子,调用的函数参数只有两个啊,所以在恢复堆栈平衡的时候我想应该是add esp,0xc 啊?但是为什么就是add esp,0x8呢?这是为什么呢?
z = Addemup(x,y)
0040101b 8b45f8 mov eax,[ebp-0x8] ; load eax with y
0040101e 50 ……
[/Quote]
call 进去后,子程序是通过ret指令才能返回的,ret指令的作用就是将call压栈的EIP又弹给了EIP.但是你压栈的两个参数还在栈上,所以调用者要注意平衡一下.

21,458

社区成员

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

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