Ily*_*lya 15 c function return-value calling-convention
我是C的新手,有一件事我无法理解.当函数返回不大于寄存器的东西时 - 我的编译器把它放在EAX中.当我返回大结构(不是指针而是结构本身)时 - 它通过堆栈返回.
我的问题是:编译器如何知道如何调用另一个对象导出的函数?有一个调用约定(比如stdcall)但它是关于传递参数,而不是读取返回的值,对吧?
应该有一些规则,如"如果声明的返回值大于EAX,则从[bp -...]"获取.
还有一个:是否正确地说我想要返回的对象,比寄存器大,应该存储在堆中并由指针返回以防止所有堆栈操作?
谢谢.
Jon*_*Jon 18
返回值传递给调用者的方式也是函数调用约定的一部分.看到这里.
例如,关于cdecl:
该
cdecl调用约定是由许多C系统的x86架构使用.在中cdecl,函数参数以从右到左的顺序被压入堆栈.函数返回值在EAX寄存器中返回(浮点值除外,它们在x87寄存器ST0中返回).
[...]
Run Code Online (Sandbox Code Playgroud)
解释有一些变化
cdecl,特别是如何返回值.因此,为不同的操作系统平台和/或不同的编译器编译的x86程序可能是不兼容的,即使它们都使用cdecl约定而不调用底层环境.一些编译器在EAX:EDX中返回长度为2个寄存器或更少的简单数据结构,并且需要异常处理程序(例如,定义的构造函数,析构函数或赋值)进行特殊处理的较大结构和类对象在内存中返回.为了传递"in memory",调用者分配内存并将指针作为隐藏的第一个参数传递给它; callee填充内存并返回指针,返回时弹出隐藏的指针.
如果在堆上分配内存,堆栈操作将比必要的堆操作快得多,因此堆栈总是更快.唯一的原因(在C中)你可能想要返回指向堆上的东西的指针是因为它不适合堆栈.
澄清:
在上面的最后一句中,"你可能想要的唯一理由......"不应被解释为"通常没有理由返回指针".相反,我的意思是" 如果你能在不返回指针的情况下做你需要的东西,那么决定使用指针的唯一理由就是......".
当然,有很多正当理由可以回答Chris的功能,因为Chris在他自己的回答中说,但我只是在讨论你不需要这样做的情况.
换句话说,尽可能按价值返回; 必要时使用指针.