C调用约定和传递的参数 [英] C calling conventions and passed arguments

查看:77
本文介绍了C调用约定和传递的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Linux(或OS X)上进行函数调用时,被调用者可以修改堆栈上的参数值吗?我当时的假设是,由于调用者是清理它们的人,因此在函数调用之后它们应包含相同的值.但是我发现带有-O2的GCC正在修改在堆栈上传递给它的参数.我还寻找了包括System V i386调用约定在内的文档,但无法找到对此的确定性答案.

When making a function call in Linux (or OS X for that matter), can the callee modify the values of the arguments on the stack? I was under the assumption that since the caller is the one that cleans them up, that they should contain the same values after the function call. However I found that GCC with -O2 was modifying parameters that were passed to it on the stack. I have also looked for documentation including the System V i386 calling conventions, but was unable to find a definitive answer to this.

这是我正在调试的一些示例代码.

Here is some sample code I was debugging.

pushl %eax       # %eax = 0x28
call _print_any
popl %eax
                 # %eax is now 0x0a

我认为GCC在堆栈上修改该参数是可以的,但我想知道可以可以在哪里指定.

I would assume that GCC modifying that parameter on the stack is fine, but I want to know where it is specified that it can do so.

推荐答案

尽管调用者(在某些调用约定中)是清理参数的对象,但实际上它所做的只是释放空间先前在堆栈上分配的用于保存参数值的对象.被调用方可以在函数执行期间自由地修改值,因为调用方以后将不再查看它们的值.

Although the caller (in some calling conventions) is the one that cleans up the arguments, all it's really doing is deallocating the space previously allocated on the stack to hold the argument values. The callee is free to modify the values during execution of the function, because the caller isn't going to look at their values later.

在您发布的示例中,GCC发出了popl %eax指令以释放该参数在堆栈上占用的空间.它真正需要做的就是将%esp加4(x86上的堆栈在内存中向下扩展 ),执行popl %eax指令是执行此操作的最短和最快的方法.如果编译器需要释放20个值,则可能会直接修改%esp而不是发出20个popl指令.

In the example you posted, GCC has emitted the popl %eax instruction to deallocate the space taken by the parameter on the stack. All it really needs to do is add 4 to %esp (the stack on x86 grows downwards in memory), and executing the popl %eax instruction is the shortest and fastest way to do this. If the compiler needed to deallocate 20 values, it would probably modify %esp directly instead of emitting 20 popl instructions.

您可能会发现以下代码未使用%eax的新值.

You will probably find that the new value of %eax is not used in the following code.

这篇关于C调用约定和传递的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆