Zurückgeben eines __m128d aus der MASM-Prozedur an einen C-Aufrufer

9

Ich portiere eine Funktion von Inline-Assembly zu MASM in Visual Studio 2013 und habe Probleme, einen Rückgabewert daraus zu erhalten.

Hier ist der C-Aufrufer und der Assembly-Funktionsprototyp:

%Vor%

Und die Assembly-Funktion:

%Vor%

Wie ich die Konvention für MASM verstehe, werden Rückgabewerte normalerweise über das EAX-Register zurückgegeben. Da ich versuche, einen 128-Bit-Wert zurückzugeben, nehme ich an, dass ein out-Parameter der richtige Weg ist. Wie Sie in der Assembly-Liste 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?

    
jaket 09.12.2014, 19:18
quelle

1 Antwort

3

Für Bildungszwecke habe ich eine Version Ihrer Funktion geschrieben, die intrinsics verwendet:

%Vor%

Dann habe ich mit dem VC ++ x64-Compiler mit cl /c /O2 /FA absmax.cpp kompiliert, um einen Assembly-Eintrag zu generieren (bearbeitet, um Zeilenkommentare zu entfernen):

%Vor%

Beachten Sie, dass x64 standardmäßig eine __fastcall -Konvention verwendet und die Parameter im Stack schattiert. Ich sehe, dass der out-Parameter tatsächlich indirekt über r8 geschrieben wird, was der dritte ganzzahlige Parameter für x64-Code ist. per MSDN . Ich denke, wenn Ihr Assemblercode diese Parameterkonvention annimmt, wird es funktionieren.

Der schattierte Stapelspeicherbereich wird nicht mit den tatsächlichen Parameterwerten initialisiert. Es ist für Callees gedacht, wenn sie einen Platz brauchen, um die Werte zu speichern, während sie die Register benutzen. Aus diesem Grund erhalten Sie in Ihrem Code einen Nullwert-Dereferenzierungsfehler. Es gibt einen Konflikt bei der Aufrufkonvention. Der Debugger kennt die Aufrufkonvention, sodass er den registrierten Wert für den Parameter anzeigen kann.

    
Colin Robertson 18.12.2014, 22:31
quelle

Tags und Links