使用 SSE 将浮点值从 Assembler DLL 返回到 C++
Posted
技术标签:
【中文标题】使用 SSE 将浮点值从 Assembler DLL 返回到 C++【英文标题】:Returning float value from Assembler DLL to C++ using SSE 【发布时间】:2016-12-04 11:17:37 【问题描述】:我在将浮点值从 DLL 汇编程序返回到 C++ 程序时遇到问题。我想它应该在 xmm0 寄存器中处理,我错了吗?这是主文件:
#include "stdafx.h"
#include<windows.h>
#include<iostream>
#include <cstdio>
#include <thread>
#include <vector>
using namespace std;
extern "C" float _stdcall MyProc1(float begin, float end, float x2 ,float x1, float x0); //dll assembler
int main(int argc, _TCHAR* argv[])
float suma=0;
suma = MyProc1(12.75,9.3,0,0,1);
cout << std::hex<< suma << endl;
getchar();
return 0;
这是我的汇编程序 DLL:
.686p
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE
INCLUDE C:\masm32\include\windows.inc
.mmx
.xmm
.DATA
pi dd 3.14159265358979 ; constant
.CODE
DllEntry PROC hInstDLL:HINSTANCE, reason:DWORD, reserved1:DWORD
mov eax, TRUE
ret
DllEntry ENDP
MyProc1 proc b:DWORD, e:DWORD, x2: DWORD, x1: DWORD, x0:DWORD
movss xmm0,[b]
ret
MyProc1 endp
END DllEntry
返回值为-1.#IND,为什么?
【问题讨论】:
您在函数声明中使用的浮点类型实际上使用 mm0 寄存器作为返回值,但 xmm 寄存器完全不同,可能您应该使用类型 __m128 而不是浮点来声明您的函数 @arash 在 x86 上没有使用 MMX 寄存器 (mm*
) 来传递或返回值的调用约定。要么使用 x87 浮点堆栈,要么使用 SSE 寄存器。
stdcall
非常具体。浮点数在 FPU 堆栈的顶部返回。您可以在函数中使用 SSE 指令,但最终浮点结果必须加载到 FPU 堆栈的顶部。在这个简单的情况下,movss xmm0,[b]
应该替换为 fld [b]
假设您在 xmm0 中有一个值(以 mov [b] 到 xmm0 为例),并且您想将一个 32 位浮点数(单个标量)放在您的 FPU 堆栈的顶部可以在 CPU 堆栈上分配空间,将 32 位值存储到堆栈位置,然后将其加载到 FPU 堆栈的顶部。例如:movss xmm0, [b]
push eax
movss dword ptr [esp], xmm0
fld dword ptr [esp]
pop eax
ret
。推送可以是任何 32 位易失性寄存器(可以通过函数修改的寄存器)。放在堆栈上的值不相关。我们只想分配 4 个字节(你也可以使用 sub esp, 4
)
这是真的,就目前而言:MMX 在 80 位 x87 寄存器的低 64 位上具有别名。但是你不能简单地说它们是相同的寄存器,然后就这样。您不能同时将它们用于 MMX 和 FPU 操作。您必须发出EMMS
指令来“清除”与 MMX 一起使用的寄存器,然后才能将它们用于 x87 FPU,并且没有允许在 MMX 寄存器中返回值的调用约定,所以如果你想返回一个浮点值,您实际上必须在函数结束前调用EMMS
。 @arash
【参考方案1】:
这是非常特定于编译器的,但我猜您使用的是 32 位 Microsoft 编译器。
在这种情况下,由于您已将函数定义为返回浮点数,因此您需要将结果放在浮点堆栈的顶部。
检查您的 C++ 代码的汇编输出以确定是否存在 - 您应该在函数调用后看到 fst
或 fstp
指令。
【讨论】:
它不是特定于编译器的,而是特定于 ABI 的。至少在 Windows 上,主要的 32 位 C++ ABI 将在浮点堆栈顶部 (fp(0)
) 或 xmm0
/ymm0
中返回浮点值。以上是关于使用 SSE 将浮点值从 Assembler DLL 返回到 C++的主要内容,如果未能解决你的问题,请参考以下文章