2016-12-04 1 views
2

DLLアセンブラからC++プログラムに浮動小数点値を返すことに問題があります。私はxmm0レジスタで処理する必要があると思いますが、間違っていますか?ここSSEを使用してAssembler DLLからC++に浮動小数点値を戻す

#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、なぜ?

+1

関数宣言で使用した浮動小数点型は、実際にはmm0レジスタを戻り値として使用しますが、xmmレジスタはまったく異なります。floatではなく__m128型の関数を宣言する必要があります。 – Arash

+1

@arash x86では、 MMXレジスタ( 'mm *')を使用して値を渡すか返す。 x87浮動小数点スタックが使用されるか、またはSSEレジスタが使用されます。 –

+1

'stdcall'は非常に特殊です。 floatはFPUスタックの先頭に返されます。関数内でSSE命令を使用することもできますが、最終的に浮動小数点結果はFPUスタックの最上部にロードする必要があります。この簡単な例では、 'movss xmm0、[b]'は 'fld [b]'と置き換えなければなりません。 –

答えて

1

これはコンパイラ固有のものですが、私は32ビットMicrosoftコンパイラを使用していると思います。

この場合、関数を定義して浮動小数点数を返すため、結果を浮動小数点スタックの最上部に配置する必要があります。

C++コードのアセンブリ出力を確認して確認してください。関数呼び出しの後にfstまたはfstp命令があるはずです。

+2

コンパイラ固有ではなく、ABI固有のものです。少なくともWindows上の主要な32ビットC++ ABIは、浮動小数点スタックの先頭( 'fp(0)')または 'xmm0' /' ymm0'のいずれかに浮動小数点値を返します。 –

関連する問題