Ich baue seit einer Weile an einem ByteCode Interpreter.
Die einzelnen ByteCodes sind in Assembler-Funktionen unterteilt, die ich der Reihe nach per jump-Befehl direkt anspringe.
Wenn ich versuche einen Float Wert in einen String (mit "wax_asm_f2u") umzuwandeln, führt dies in der SysUtils.FloatToText Funktion zu einer Access Violation.
Hier die Funktion zum Auslesen des 4 Byte Float Wertes aus dem Byte-Stream, welcher oben auf den Stack gelegt wird.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure wax_asm_fconst_x(); assembler; {$IFDEF FPC}nostackframe;{$ENDIF} asm @GET_ARG1 : mov rdx, [rbp] xor rcx, rcx mov ecx, dword ptr [rdx] push rcx add qword ptr [rbp], $04 @RETURN : mov rsi, $01 jmp rbx end; |
Hier die Funktion zum Wandeln des 4 Byte Float Wertes, welcher oben auf dem Stack liegt.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| procedure wax_asm_f2u(); assembler; {$IFDEF FPC}nostackframe;{$ENDIF} asm @GET_ARG : movss xmm0, dword ptr [rsp] pop rcx
@CONVERT : push rbp push rbx sub rsp, $20 mov rbp, rsp call wax_float_to_string add rsp, $20 pop rbx pop rbp
push rax
@RETURN : mov rsi, $01 jmp rbx end; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| function wax_float_to_string(AValue : TWax_Float) : TWax_String; stdcall; var lBuffer : Array[0..63] of WideChar; len : Integer; lVal : TWax_Double; begin lVal := AValue; len := FloatToText(lBuffer, lVal, fvExtended, ffGeneral, 15, 0, WAX_FORMAT_SETTINGS); [...] end; |
Fehlerstelle in GetBcdBytes:
Delphi-Quelltext
1:
| 00000000004307A6 660F7F742420 movdqa dqword ptr [rsp+$20],xmm6 |
Seit Tagen zermürbe ich mir das Hirn und verstehe nicht was ich falsch mache.
Muss man beim Aufruf mit XMM Registern noch etwas beachten?
Die 16 Byte Ausrichtung lege ich zu Beginn mit "System.SetMinimumBlockAlignment(mba16Byte)" fest.
Wäre wirklich klasse, wenn ihr mir hiermit weiterhelfen könntet.