C:通过堆栈/寄存器的问题返回值 [英] C: Return value via stack/register question

查看:129
本文介绍了C:通过堆栈/寄存器的问题返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新的C,有一件事我无法理解。
当函数返回的东西是不是比寄存器大 - 我的编译器把它放在EAX。
当我回到大结构(没有指针,但结构本身) - 它是通过栈返回

我的问题是:编译器如何知道如何调用由另一个对象导出的功能?
有一个调用约定(如STDCALL),但它是关于传递参数,不读返回值吧?

有应该像一些规则,如果返回值声明为EAX比大,比把它从[BP -...]。

还有一:这将是正确地说,对象我想返回,比寄存器大应存放在堆和指针prevent都比堆栈操作恢复

感谢。


解决方案

返回值传递给调用者的方式是函数调用约定的一部分。请参见这里

例如,对于 CDECL


  

CDECL 调用约定使用
  许多空调系统用于x86
  建筑。在 CDECL ,功能
  参数被压入堆栈在
  从右到左的顺序。函数返回
  值在EAX返回
  登记(除浮点
  值,这是在使用x87返回
  注册ST0)。


  [...]


  

有在一些变
  国米pretation CDECL ,尤其是
  在如何返回值。结果是,
  x86程序编译为不同
  操作系统平台和/或通过
  不同的编译器可以
  不相容的,即使他们都使用
  在 CDECL 公约,不叫
  出到底层环境。
  一些编译器返回简单的数据
  为2的长度的结构
  寄存器或更少在EAX:EDX和
  较大的结构和类对象
  需经特殊处理
  异常处理程序(例如,定义的
  构造函数,析构函数,或
  转让)在内存中返回。至
  通过存储器,来电中分配
  存储器和将指针传递到它作为一个
  隐藏第一个参数;被叫方
  填充存储器,并返回
  指针,弹出隐藏的指针
  返回时。


栈操作会如果在堆上分配内存为比堆操作快得多得多必要,所以堆栈总是快。的唯一原因(C语言),你可能要返回一个指针的东西堆是因为它不适合在堆栈中。

澄清:

在上面的最后一句,你可能想......唯一的理由不应该作为PTED间$ P $,通常没有理由返回一个指针。相反,我的意思是的如果你能做到你需要什么,而不返回一个指针的,唯一的原因来决定使用指针反正就是......

当然,也有很多正当的理由返回从函数指针作为克里斯在他自己的答案州,但我只是说说,你别案件的需求的这样做。

在换句话说,由价值回归时即可;使用指针,当你必须

I am new to C, and there is one thing I can not understand. When function returns something that is not bigger than register -- my compiler puts it in EAX. When I return big structure (not pointer but structure itself) -- it is returned via stack.

My question is: how compiler knows how to call function exported by another object? There is a calling conventions (like stdcall) but it is about passing the arguments, not reading the returned value, right?

There should be some rule like "If return value declared to be larger than EAX, than take it from [bp-...]".

And one more: would it be right to say that objects I want to return, larger than register should be stored in heap and returned by pointer to prevent all than stack manipulations?

Thanks.

解决方案

The way that the return value is passed to the caller is part of the function calling conventions as well. See here.

For example, regarding cdecl:

The cdecl calling convention is used by many C systems for the x86 architecture. In cdecl, function parameters are pushed on the stack in a right-to-left order. Function return values are returned in the EAX register (except for floating point values, which are returned in the x87 register ST0).

[...]

There are some variations in the interpretation of cdecl, particularly in how to return values. As a result, x86 programs compiled for different operating system platforms and/or by different compilers can be incompatible, even if they both use the cdecl convention and do not call out to the underlying environment. Some compilers return simple data structures with the length of 2 registers or less in EAX:EDX, and larger structures and class objects requiring special treatment by the exception handler (e.g., a defined constructor, destructor, or assignment) are returned in memory. To pass "in memory", the caller allocates memory and passes a pointer to it as a hidden first parameter; the callee populates the memory and returns the pointer, popping the hidden pointer when returning.

The stack manipulations are going to be much much faster than the heap manipulations necessary if you allocate memory on the heap, so stack is always faster. The only reason (in C) you might want to return a pointer to something on the heap is because it won't fit on the stack.

Clarification:

In the last sentence above, "the only reason you might want..." should not be interpreted as "there is normally no reason to return a pointer". Rather, I mean "if you can do what you need without returning a pointer, the only reason to decide to use a pointer anyway is...".

Of course there are many valid reasons to return pointers from functions as Chris states in his own answer, but I 'm only talking about the cases where you don't need to do so.

In other words, return by value when you can; use pointers when you must.

这篇关于C:通过堆栈/寄存器的问题返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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