smw*_*dia 5 c c++ x86 assembly calling-convention
目前我正在编写一些汇编语言程序.正如一些惯例所说,当我想向调用者返回一些值时,比如一个整数,我应该在EAX寄存器中返回它.现在我想知道如果我想返回一个float,一个double,一个枚举,甚至一个复杂的结构.如何返回这些类型的值?
我可以想到在EAX中返回一个指向内存中真实值的地址.但这是标准方式吗?
非常感谢~~~
AnT*_*AnT 10
如果调用者是您的代码,这完全取决于您.如果呼叫者不在您的控制之下,您必须遵循其现有惯例或一起制定您自己的惯例.
例如,在x86平台上,当FPU指令处理浮点运算时,函数的结果将作为FPU寄存器堆栈的最高值返回.(如果你知道,x86 FPU寄存器被组织成各种各样的"循环堆栈").那时它既不是float也不是double,它是一个存储有内部FPU精度的值(可能高于float或者double并且调用者有责任从FPU堆栈的顶部检索该值并将其转换为它想要的任何类型.实际上,这就是典型的FPU指令的工作原理:它从FPU堆栈的顶部获取其参数,并将结果推回到FPU堆栈.通过以相同的方式实现您的功能,您基本上可以使用您的函数模拟"复杂"FPU指令 - 这是一种相当自然的方式.
当SSE指令处理浮点运算时,您可以选择一些SSE寄存器用于相同的目的(xmm0就像EAX用于整数一样).
对于复杂结构(即大于寄存器或寄存器对的结构),调用者通常会将指针传递给函数的保留缓冲区.函数会将结果放入缓冲区.换句话说,在引擎盖下,函数永远不会真正"返回"大对象,而是在调用者提供的内存缓冲区中构造它们.
当然,您可以使用此"内存缓冲区"方法返回任何类型的值,但是使用较小的值(即标量类型的值),使用寄存器比使用内存位置要高效得多.这也适用于小型结构.
枚举通常只是某种整数类型的概念包装.因此,返回枚举或整数之间没有区别.
应该返回double作为堆栈中的第1项.
这是一个C++代码示例(x86):
double sqrt(double n)
{
_asm fld n
_asm fsqrt
}
Run Code Online (Sandbox Code Playgroud)
如果您更喜欢手动管理堆栈(节省一些CPU周期):
double inline __declspec (naked) __fastcall sqrt(double n)
{
_asm fld qword ptr [esp+4]
_asm fsqrt
_asm ret 8
}
Run Code Online (Sandbox Code Playgroud)
对于复杂类型,您应该传递指针,或返回指针.