2016-12-04 14 views
2

У меня возникла проблема с возвратом значения float из программы DLL Assembler в C++. Я полагаю, что его нужно обрабатывать в регистре xmm0, я ошибаюсь? Вот главный файл:Возвращаемое значение float из библиотеки Assembler DLL в C++ с использованием SSE

#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 совершенно разные, возможно, вы должны объявить свою функцию с типом __m128 вместо float – 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. Основные 32-битные C++ ABI, по крайней мере в Windows, вернут значение с плавающей запятой либо в верхней части стека с плавающей запятой ('fp (0)'), либо в 'xmm0' /' ymm0'. –