关于汇编的push/pop的问题请教

ware_soft 2009-06-22 06:52:15
push之后必须用pop吗?


下面的我这种情况需不需要啊,如果需要/不需要,请各位都说明原因。

push 1113
call csvlp
add esp,4
;
test eax,1
jnz lp02
lp02:

mov dword ptr r21,100
mov dword ptr r19,offset oapgtm
jmp lp00
lp00:
mov edx,dword ptr r23
mov dword ptr r24,edx
push eax
mov eax,dword ptr r24
mov ebx,dword ptr STrpgtm
mul ebx
mov dword ptr r24,eax
pop eax
mov edx,dword ptr r19
add dword ptr r24,edx
...全文
689 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
ware_soft 2009-06-23
  • 打赏
  • 举报
回复
push 1113
call csvlp
add esp,4
;
test eax,1
jnz lp02
lp02:

mov dword ptr r21,100
mov dword ptr r19,offset oapgtm
jmp lp00
lp00:
mov edx,dword ptr r23
mov dword ptr r24,edx
push eax


这里的话,上面调用函数把值放入了eax中,下面在push一个eax会不会把上面函数的返回值放进去啊?
这里有影响否?
ware_soft 2009-06-23
  • 打赏
  • 举报
回复
push 1113
call csvlp
add esp,4
;
test eax,1
jnz lp02
lp02:

mov dword ptr r21,100
mov dword ptr r19,offset oapgtm
jmp lp00
lp00:
mov edx,dword ptr r23
mov dword ptr r24,edx
push eax


这里的话,上面调用函数把值放入了eax中,下面在push一个eax会不会把上面函数的返回值放进去啊?
这里有影响否?
coohai 2009-06-23
  • 打赏
  • 举报
回复
先要看模式,还要看子过程的调用协议,和参数
32位下,push xx; 相当于 sub esp,4; mov [esp],xx;
pop xx; 相当于 mov xx, [esp]; add esp, 4;
不同的只是push和pop不影响标志位,而add和sub会影响.

对于C协议,由调用者平衡堆栈,所以调用前压参数入栈,调用后用语句add esp, n*4; 平衡堆栈,(n=参数个数)
对于StdCall协议,由被调用的子过程自己平衡堆栈,调用前压参数入栈,调用后不用add esp, n*4; 堆栈就已经平衡了。
只是,在该子过程内部返回是用的语句是ret n*4;

所以push 不一定对应有pop,重要的是要让堆栈指针esp在使用前后一致.
pla_007 2009-06-23
  • 打赏
  • 举报
回复
这是2个不相关的概念。
上面cnzdgs已经说的很清楚了,add esp,N是用来平衡堆栈的。
跟你结果放到哪里无关。

[Quote=引用 10 楼 ware_soft 的回复:]
也就是我这里调用完call csvlp之后,把函数的结果放到了eax里,我最后不用在pop eax就可以了,因为有了add esp 4对不?
[/Quote]
pla_007 2009-06-23
  • 打赏
  • 举报
回复
MARK学习下,最早的时候还不知道可以这么干,经过暴风门之后,晓得了。
ware_soft 2009-06-23
  • 打赏
  • 举报
回复
也就是我这里调用完call csvlp之后,把函数的结果放到了eax里,我最后不用在pop eax就可以了,因为有了add esp 4对不?
ware_soft 2009-06-23
  • 打赏
  • 举报
回复
也就是我这里调用完call csvlp之后,把函数的结果放到了eax里,我最后不用在pop eax就可以了,因为有了add esp 4对不?
cnzdgs 2009-06-22
  • 打赏
  • 举报
回复
push不一定要对应pop,最常见的有两种情况:
1、函数调用时通过栈来传递参数(你上面代码就是这种情况)。如果函数使用ret N指令返回,返回后会自动把esp加N,例如函数定义了一个DWORD型参数,则使用ret 4返回,调用时只需要push一个DWORD,不需要pop;如果函数使用ret指令返回,调用者需要自己处理栈平衡,通常是在call指令后面写一条add esp,N指令,例如push了一个DWORD,后面就add esp,4,这种方式比前一种麻烦一点,但可以支持不定个数的参数。
2、函数入口处执行
push ebp
mov ebp,esp
push ecx ; 分配一个DWORD型局部变量
……
函数中使用[ebp-4]来访问这个局部变量
函数返回前执行
mov esp,ebp
pop ebp

此外还有很多特殊情况只有push没有pop,等到汇编语言掌握到一定程度后自然就清楚了。
friendly_ 2009-06-22
  • 打赏
  • 举报
回复
push 1113
call csvlp
add esp,4
-------------------------------------------------
push 1113 压入参数,即把csvlp需要的参数入栈,在csvlp中会从栈中取出使用,在csvlp中一般会这样取
push esp;mov ebp,esp ;mov eax ,[ebp+8]其中[ebp+8]就是压入栈中的1113。
add esp,4用来平栈 一般c调用这样用,由调用者平栈,stdcall一般会用 ret 4 这种形式。
push 入栈,pop出栈,并不是同时必须的,完全可以用mov 的方式入栈,用mov的方式取栈中数据。
push pop 配对出现的地方一般是在子程序中,是为了保存子程序调用前寄存器的值,保证子程序不修改寄存器的值,但也不是必须的。
nanlingcg 2009-06-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 BAYNPU 的回复:]
32位可以直接使用立即数压栈!
[/Quote]
是了,刚查到。。。
nanlingcg 2009-06-22
  • 打赏
  • 举报
回复
这大概是反汇编人家的软件得的代码?怎么那么绕人呢?
搞破解啊?
BAYNPU 2009-06-22
  • 打赏
  • 举报
回复
32位可以直接使用立即数压栈!
BAYNPU 2009-06-22
  • 打赏
  • 举报
回复
看了上面程序它调用call (csvlp)的子程序,在往下面是一条 add esp,4 它主要是负责主程序平衡堆栈.
nanlingcg 2009-06-22
  • 打赏
  • 举报
回复
push 1113 ???这也可以吗?
buzuibuxiu 2009-06-22
  • 打赏
  • 举报
回复
push之后不一定非要用,看你的用途了!如果你调用你的子程序的时候那样的话就一定要了,除非你手动的跳动你的sp或者esp。否则的话子程序在返回的时候出栈将找不到原程序的执行位置,即无法返回!你这个地方不知道是不是出于子程序的位置!
而且如果你的eax中并未保存以后要用到的数据的话你就不要push了!
但是一般push之后都要用到保存在栈区里面的值!

21,499

社区成员

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

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