2016-12-04 8 views
2

DLL 어셈블러에서 C++ 프로그램으로 float 값을 반환하는 데 문제가 있습니다. xmm0 레지스터에서 처리해야한다고 생각합니다. 틀렸습니까? 여기SSE를 사용하여 Assembler DLL에서 C++로 float 값 반환

#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

함수 선언에 사용 된 float 유형은 실제로 mm0 레지스터를 반환 값으로 사용하지만 xmm 레지스터는 완전히 다릅니다. float 대신 __m128 유형의 함수를 선언해야합니다. – Arash

+1

@arash x86에 대한 호출 규칙은 없습니다 MMX 레지스터 ('mm *')를 사용하여 값을 전달하거나 반환합니다. x87 부동 소수점 스택이 사용되거나 SSE 레지스터가 사용됩니다. –

+1

'stdcall'은 매우 구체적입니다. 부동 소수점은 FPU 스택 맨 위에 반환됩니다. 함수에서 SSE 명령어를 사용할 수 있지만 결국 부동 결과는 FPU 스택의 맨 위에로드되어야합니다. 이 단순한 경우에'movss xmm0, [b]'는'fld [b]'로 대체되어야한다. –

답변

1

이것은 매우 컴파일러마다 다르지만 32 비트 Microsoft 컴파일러를 사용하고있는 것 같습니다.

이 경우 부동 소수점을 반환하도록 함수를 정의 했으므로 결과를 부동 소수점 스택의 맨 위에 배치해야합니다.

C++ 코드의 어셈블리 출력을 확인하여 확실하게 확인하십시오. 함수 호출 후에 fst 또는 fstp 명령어가 표시되어야합니다.

+2

컴파일러 관련 정보가 아닌 ABI 관련 정보입니다. 최소한 Windows에서 주요 32 비트 C++ ABI는 부동 소수점 스택 ('fp (0)') 또는'xmm0' /'ymm0'에서 부동 소수점 값을 반환합니다. –