简体   繁体   English

如何将float作为参数传递(内联汇编)?

[英]How to pass float as argument (inline-assembly)?

How to pass float as function argument (external call) and return float in inline assembly? 如何将float作为函数参数传递(外部调用)并在内联汇编中返回float? An example below doesn't work and is crashing the app. 下面的示例不起作用,并且使应用程序崩溃。 The comments are mine, so they might be also wrong. 这些评论是我的,因此它们也可能是错误的。

The first two lines are added by myself just for this example. 仅针对此示例,我自己添加了前两行。 Originally I start with two float values on st(0) and st(1) and there's nothing I can do about that. 最初,我从st(0)和st(1)上的两个float值开始,对此我无能为力。

fld     a               ; load float 'a' on st(0)
fld     b               ; load float 'b' on st(0), 'a' is now st(1)
sub     esp, 4          ; make room for float 
fstp    dword ptr [esp] ; push st(0) on stack, pop st(0)
mov     ecx, ebp        ; move 'this' on ecx
call    Class::ModValue ; returns float on st(0)
fcompp                  ; compare returned st(0) with st(1)    
fnstsw  ax
test    ah, 41h
jnz     Exit_label

The code snippet above is inside asm{} block, there is more unimportant code before and after that. 上面的代码段在asm{}块中,在此之前和之后还有更多不重要的代码。 The crash is happening between 1st line of this code fragment and ModValue function call. 崩溃发生在此代码片段的第一行和ModValue函数调用之间。

Function signature: 功能签名:

float Class::ModValue(float value)
{
    _LOG("ModValue") // doesn't show
    return value;
}

Compiler: VisualStudio, Architecture: x86, Calling convention: __thiscall 编译器:VisualStudio,体系结构:x86,调用约定: __thiscall

if it's a __thiscall 如果是__thiscall

According to msdn: 根据msdn:

The __thiscall calling convention is used on member functions and is the default calling convention used by C++ member functions that do not use variable arguments. __thiscall调用约定在成员函数上使用,并且是不使用变量参数的C ++成员函数使用的默认调用约定。 Under __thiscall, the callee cleans the stack, which is impossible for vararg functions. 在__thiscall下,被调用方将清理堆栈,这对于vararg函数是不可能的。 Arguments are pushed on the stack from right to left, with the this pointer being passed via register ECX, and not on the stack, on the x86 architecture. 在x86架构上,参数从右向左推入堆栈,并且此指针通过寄存器ECX传递,而不是通过堆栈传递。

source: https://msdn.microsoft.com/en-us/library/ek8tkfbw.aspx 来源: https : //msdn.microsoft.com/en-us/library/ek8tkfbw.aspx

then a small example: 再举一个小例子:

float DoStuffs(void *pThis, float a)
{
    float flResult = 0.0f;

    __asm
    {
        push a;
        mov ecx, pThis;
        call Class::ModValue;
        fstp[flResult];
    }
    return flResult;
}

Some extended example: 一些扩展的示例:

class Test
{
public:
    float b;   
    float Add(float a);

};

float Test::Add(float a)
{
    return a + this->b;
}

float CallTest(void* pThis, float x)
{
    float flResult = 0.0f;

    __asm
    {
        push x;
        mov ecx, pThis;
        call Test::Add;
        fstp[flResult];
    }

    return flResult;
}

int main()
{
    void* m = malloc(4);

    *(float*)m = 2.0f;

    std::cout << CallTest(m, 2.1f) << std::endl;

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM