Przesyłam funkcję z wbudowanego zestawu do MASM w programie Visual Studio 2013 i mam problem z uzyskaniem z niej wartości zwracanej.Zwracanie procedury __m128d z MASM do wywołującego C
Oto rozmówcy C i prototyp funkcji montaż:
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;
}
a funkcja montaż:
.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
Jak rozumiem Konwencji o MASM, zwracane wartości są zwykle zwrócone na zewnątrz przez Rejestracja EAX. Jednakże, ponieważ próbuję zwrócić 128-bitową wartość, zakładam, że parametr wyjściowy jest do zrobienia. Jak widać na liście złożenia, przypisanie parametru out (movaps [result]
) powoduje naruszenie zasad dostępu (Lokalizacja odczytu naruszenia dostępu 0x00000000). Sprawdziłem adres wyniku w debugerze i wygląda dobrze.
Co robię źle?
Czy adres jest odpowiednio wyrównany? – Mehrdad
Czy to możliwe, że można zmodyfikować wywołującego, aby zamiast tego zwrócił wskaźnik do __m128d? – mbomb007
@Mehrdad. Tak to jest. '__m128d' jest zdefiniowany przez __declspec, aby właściwie go wyrównać i dwukrotnie sprawdziłem adres w debugerze. – jaket