从程序集中调用的C++方法返回对象数据

Returning Object Data from C++ Method Called in Assembly

本文关键字:方法 返回 对象 数据 C++ 程序 程序集 集中 调用      更新时间:2023-10-16

我有一个用C++编写的方法,它返回一个对象。这种方法被称为via assembly(原因很冗长)。示例:

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++/汇编函数调用并没有起到很大的作用。感谢任何能提供帮助的人。

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

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

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