
3个回答
展开全部
原理是这样的:
当call 一个函数的时候,程序跑到函数体去执行,执行完了需要回到call 后面的那条指令去执行
现在的问题是,函数体执行完了怎么回到call后面的那条指令去继续执行呢?
既然需要回去,就必须要把返回地址保存起来,而返回地址事实上就是保存在栈中的
call function
事实上做的是
push ip(事实上是没有这条指令的)
jmp function
函数体结束的时候需要有ret指令
ret指令做的事情是
pop ip(事实上是没有这条指令的,就是这个意思)
这样的话,楼主应该很清楚的知道,返回地址是保存在函数调用者的栈帧顶部的
而函数返回的时候需要用到这个地址(电脑不是智能的,在返回的时候会直接从栈顶弹出一个字到这个地址去运行)
因此,在函数体内部如果栈不平衡了函数体返回就会出错
原理上就是这样,只要函数体内 运行前与运行后堆栈不平衡,函数就不能正确返回
所以单push是不行的
不过影响堆栈的指令不仅仅只有push和pop两条指令
除了直接操作堆栈的指令pushad pushf这些指令以外
像修改 sp值的指令也会影响堆栈,所以 影响堆栈平衡的指令都是不可以出现的
当call 一个函数的时候,程序跑到函数体去执行,执行完了需要回到call 后面的那条指令去执行
现在的问题是,函数体执行完了怎么回到call后面的那条指令去继续执行呢?
既然需要回去,就必须要把返回地址保存起来,而返回地址事实上就是保存在栈中的
call function
事实上做的是
push ip(事实上是没有这条指令的)
jmp function
函数体结束的时候需要有ret指令
ret指令做的事情是
pop ip(事实上是没有这条指令的,就是这个意思)
这样的话,楼主应该很清楚的知道,返回地址是保存在函数调用者的栈帧顶部的
而函数返回的时候需要用到这个地址(电脑不是智能的,在返回的时候会直接从栈顶弹出一个字到这个地址去运行)
因此,在函数体内部如果栈不平衡了函数体返回就会出错
原理上就是这样,只要函数体内 运行前与运行后堆栈不平衡,函数就不能正确返回
所以单push是不行的
不过影响堆栈的指令不仅仅只有push和pop两条指令
除了直接操作堆栈的指令pushad pushf这些指令以外
像修改 sp值的指令也会影响堆栈,所以 影响堆栈平衡的指令都是不可以出现的
追问
非常赞同您的观点,我还有一个令我不解的问题:当使用“loop"时,是不是包含在循环体中的指令数目不能超过一个值,否则会出错?
追答
是这样的
在16位汇编中
对与循环指令
其转移的目标地址是以当前IP内容为基地址的-128~+127范围内
这主要是受限与loop指令长度
loop指令整条指令中只有一个字节用于表示需要跳转的指令偏移
而一个字节能表示的范围就是-128~+127
loop相当于一个短转移(当然,转移之前需要判断cx-1是否为0)
如果越界转移
编译器可能会给出这样的错误:error A2075:jump destination too far: by XXbyte(s)
展开全部
push和pop不一定非得成对使用,但在call返回时,esp必须指向应该指向的位置,可以用 add esp, xxx 有时也会用 leave
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
push和pop一定事成对使用的
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询