
x86上为什么C语言调用一个函数要先把参数压栈,之后才是返回地址
2个回答
展开全部
返回地址先于参数入栈是不可能的== 因为参数入栈是调用函数通过push指令完成的 而返回地址入栈则是在call指令中自动完成的 因此如果一定要先把返回地址压栈 就需要先调用call指令 call指令返回之后 程序就已经在被调函数里面了 调用函数已经失去了控制权 不可能再通过push指令把参数压栈了……
此外额我觉得这涉及到x86的一个规范吧…… 函数调用时参数压栈和被调函数返回后参数出栈都是由调用函数来完成 被调函数不参与(否则如果两者同时参与很容易把栈搞混乱) 如果参数在返回地址上方 被调函数返回的时候 为了取得返回地址 被调函数必须先把参数出栈 这就与之前说的规范冲突了
此外额我觉得这涉及到x86的一个规范吧…… 函数调用时参数压栈和被调函数返回后参数出栈都是由调用函数来完成 被调函数不参与(否则如果两者同时参与很容易把栈搞混乱) 如果参数在返回地址上方 被调函数返回的时候 为了取得返回地址 被调函数必须先把参数出栈 这就与之前说的规范冲突了
展开全部
这个没有为什么。除了硬性的逻辑需求,就是约定。
逻辑需求就是你必须在call指令之前完成参数传递,也就是你所说的压栈,这是__cdecl调用约定。其实还有fastcall调用约定,这个在86_32环境下两个及以下参数是不需要入栈的,因为它使用ecx和edx寄存器传递。入栈顺序方面,就是约定了,这个并不是刚需,但为了保证可移植性,由人来定义的一种方法形式。
关于你说的返回地址,这个并不是主动的push rip+n什么的(而且不支持这个指令)。而是call指令的效果。
逻辑需求就是你必须在call指令之前完成参数传递,也就是你所说的压栈,这是__cdecl调用约定。其实还有fastcall调用约定,这个在86_32环境下两个及以下参数是不需要入栈的,因为它使用ecx和edx寄存器传递。入栈顺序方面,就是约定了,这个并不是刚需,但为了保证可移植性,由人来定义的一种方法形式。
关于你说的返回地址,这个并不是主动的push rip+n什么的(而且不支持这个指令)。而是call指令的效果。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询