Ich portiere eine Funktion von Inline-Assembly zu MASM in Visual Studio 2013 und habe Probleme beim Abrufen eines Rückgabewerts. HierZurückgeben einer __m128d aus MASM-Prozedur zu einem C-Aufrufer
ist der C Anrufer und der Montag Funktionsprototyp:
extern "C" void AbsMax(__m128d* samples, int len, __m128d* pResult);
__m128d AbsMax(__m128d* samples, int len)
{
__m128d absMax = { 0, 0 };
AbsMax(samples, len, &absMax);
return absMax;
}
und die Montage-Funktion:
.686 ;Target processor. Use instructions for Pentium class machines
.xmm
.model flat, c ;Use the flat memory model. Use C calling conventions
.code ;Indicates the start of a code segment.
AbsMax proc samples:PTR DWORD, len:DWORD, result:PTR XMMWORD
;; Load up registers. xmm0 is min, xmm1 is max. L is Ch0, H is Ch1.
mov ecx, [len]
shl ecx, 4
mov esi, [samples]
lea esi, [esi+ecx]
neg ecx
pxor xmm0, xmm0
pxor xmm1, xmm1
ALIGN 16
_loop:
movaps xmm2, [esi+ecx]
add ecx, 16
minpd xmm0, xmm2
maxpd xmm1, xmm2
jne _loop
;; Store larger of -min and max for each channel. xmm2 is -min.
pxor xmm2, xmm2
subpd xmm2, xmm0
maxpd xmm1, xmm2
movaps [result], xmm1 ; <=== access violation here
xor eax, eax
xor ebx, ebx
ret
AbsMax ENDP
END
Als ich die Konvention für MASM verstehen, Werte zurückgeben werden in der Regel durch die zurückgeführt EAX registrieren. Da ich versuche, einen 128-Bit-Wert zurückzugeben, nehme ich an, dass ein out-Parameter der richtige Weg ist. Wie Sie im Assembly-Listing sehen können, verursacht das Zuweisen des out-Parameters (movaps [result]
) eine Zugriffsverletzung (Access violation reading location 0x00000000). Ich habe die Adresse des Ergebnisses im Debugger überprüft und es sieht gut aus.
Was mache ich falsch?
Ist die Adresse richtig ausgerichtet? – Mehrdad
Ist es möglich, dass Sie den Aufrufer so ändern können, dass stattdessen ein Zeiger auf __m128d zurückgegeben wird? – mbomb007
@Mehrdad. Ja, so ist es. '__m128d' ist mit einer __declspec definiert, um es richtig auszurichten und ich habe die Adresse im Debugger überprüft. – jaket