如何将 float 作为参数传递(内联汇编)?
How to pass float as argument (inline-assembly)?
如何将 float 作为函数参数(外部调用)和 return 在内联汇编中传递 float?下面的示例不起作用并且使应用程序崩溃。评论是我的,所以他们也可能是错误的。
前两行是我自己加的,只是为了这个例子。最初我从 st(0) 和 st(1) 上的两个浮点值开始,对此我无能为力。
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
上面的代码片段在asm{}
块中,前后有更多不重要的代码。崩溃发生在该代码片段的第一行和 ModValue
函数调用之间。
函数签名:
float Class::ModValue(float value)
{
_LOG("ModValue") // doesn't show
return value;
}
编译器:VisualStudio,架构:x86,调用约定:__thiscall
如果是 __thiscall
根据msdn:
__thiscall 调用约定用于成员函数,是不使用可变参数的 C++ 成员函数使用的默认调用约定。在 __thiscall 下,被调用者清理堆栈,这对于 vararg 函数来说是不可能的。在 x86 架构上,参数从右到左压入堆栈,this 指针通过寄存器 ECX 传递,而不是压入堆栈。
来源:https://msdn.microsoft.com/en-us/library/ek8tkfbw.aspx
再举个小例子:
float DoStuffs(void *pThis, float a)
{
float flResult = 0.0f;
__asm
{
push a;
mov ecx, pThis;
call Class::ModValue;
fstp[flResult];
}
return flResult;
}
一些扩展示例:
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;
}
如何将 float 作为函数参数(外部调用)和 return 在内联汇编中传递 float?下面的示例不起作用并且使应用程序崩溃。评论是我的,所以他们也可能是错误的。
前两行是我自己加的,只是为了这个例子。最初我从 st(0) 和 st(1) 上的两个浮点值开始,对此我无能为力。
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
上面的代码片段在asm{}
块中,前后有更多不重要的代码。崩溃发生在该代码片段的第一行和 ModValue
函数调用之间。
函数签名:
float Class::ModValue(float value)
{
_LOG("ModValue") // doesn't show
return value;
}
编译器:VisualStudio,架构:x86,调用约定:__thiscall
如果是 __thiscall
根据msdn:
__thiscall 调用约定用于成员函数,是不使用可变参数的 C++ 成员函数使用的默认调用约定。在 __thiscall 下,被调用者清理堆栈,这对于 vararg 函数来说是不可能的。在 x86 架构上,参数从右到左压入堆栈,this 指针通过寄存器 ECX 传递,而不是压入堆栈。
来源:https://msdn.microsoft.com/en-us/library/ek8tkfbw.aspx
再举个小例子:
float DoStuffs(void *pThis, float a)
{
float flResult = 0.0f;
__asm
{
push a;
mov ecx, pThis;
call Class::ModValue;
fstp[flResult];
}
return flResult;
}
一些扩展示例:
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;
}