从Assembly中调用的C ++方法返回对象数据

时间:2013-12-12 18:35:03

标签: c++ oop assembly x86 return-value

我有一个用C ++编写的方法,它返回一个对象。这个方法是通过汇编调用的(这是一个非常冗长的原因)。例如:

Person DoStuff( int a )
{
    Person output;

    output.Name = "Koder";
    output.Age = 1337;
    output.Cash = 80.86;

    cout << "Given number is " << a << endl;

    return output;
}

我知道按价值回归是令人讨厌和糟糕的,但这个问题并非如此。调用此方法看起来像这样:

Variant vMethod = &DoStuff;
void* pMethod = vMethod.As<void*>( );

int paramVal = 78;

int* retVal = nullptr;

__asm
{
    push paramVal
    call pMethod
    mov retVal, EAX
}

当此方法的返回值为int时,这非常有效。但是现在返回一个对象,实际的call指令会引发异常。正如您所猜测的那样,例外是return语句。我知道当我以这种方式编写时会发生这种情况,但我不知道如何检索非原始(或非整数)返回值。谷歌搜索C ++ /汇编函数调用并没有帮助很多。感谢任何可以提供帮助的人。

1 个答案:

答案 0 :(得分:1)

这取决于所使用的呼叫类型Calling Convention。它还取决于编译器如何处理对象。在这种情况下,您的对象包含至少3个值,这使得所有值都不太可能适合寄存器(您的代码假设返回值将在EAX中 - 如果您返回int将会是这样)。

从查看程序集看来,您正在使用x86 32位程序集。 在这种情况下,调用约定说你应该在栈上传递参数, 对于这种情况,我认为x86位的调用约定表明你需要自己为返回值保留内存,并传递对象应存储的地址作为参数。在Windows上,返回指针(存储对象的地址)是第二个参数,在Linux上是第一个参数。

由于您未能执行此操作,DoStuff方法可能会覆盖返回地址,并导致程序在返回指令上崩溃。