Entwickler-Ecke
Algorithmen, Optimierung und Assembler - Float als Argument an Funktion in Assembler (64 Bit)
Shasta2103 - Mo 17.12.12 11:21
Titel: Float als Argument an Funktion in Assembler (64 Bit)
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.
Shasta2103 - Di 18.12.12 10:40
Ich habe die FloatToText Methode nun aus der SysUtils Unit extrahiert, um besser debuggen zu können.
Dies allein hat tatsächlich mein Problem gelöst und die Exception tritt nun nicht mehr auf.
Diese Lösung ist sicherlich nicht sauber und wird mich bestimmt eines Tages wieder einholen, doch für den
Moment erscheint mir das als akzeptabel.
jochenc - Mo 07.01.13 09:32
Aahhh super Shatsa2103, Danke dass Du auch die Lösung gepostet hast. Bin in einer ähnlichen Lage und der Tipp ist für mich sehr brauchbar. Vielleicht kannst Du auch die Endlösung posten, sobald Du sie gefunden hast. Liebe Grüße.
Shasta2103 - Mi 13.03.13 09:47
Oh, gar nicht gesehen! Entschuldige die späte Antwort.
Die FloatToText Funktion aus Delphi-Bibliothek zu extrahieren und in eine separate Unit zu kopieren, ist für mich nun auch die Endlösung, da es zu keinen weiteren Problemen führte. Das ist sicherlich keine zufriedenstellende und saubere Lösung, aber mir ist bisher nix besseres eingefallen.
Ich vermute, weil ich keine Stackframes benutze, jede Menge Register mißhandle und durch das wilde ASM hin- und hergespringe, passt irgendein Register nicht mehr, was dann zur Exception führt.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!