Autor Beitrag
Shasta2103
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25

Win7
Delphi XE2
BeitragVerfasst: Mo 17.12.12 11:21 
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.
ausblenden 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]            // in RBP die Adresse zu einem PAnsiChar-Buffer
    xor   rcx, rcx              // Register leeren
    mov   ecx, dword ptr [rdx]  // kopiere 4 Byte aus dem PAnsiChar-Buffer
    push  rcx                   // Schiebe Argument auf den Stack
    add   qword ptr [rbp], $04  // PAnsiChar-Buffer Zeiger um 4 Byte weiterschieben

  @RETURN :
    mov   rsi, $01              // Teilfunktion war erfolgreich
    jmp   rbx                   // Springe zur aufrufenden Funktion zurück
end;


Hier die Funktion zum Wandeln des 4 Byte Float Wertes, welcher oben auf dem Stack liegt.
ausblenden 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]  // Float Wert aus "wax_asm_fconst_x" in XMM0 Register
    pop    rcx

  @CONVERT :
    push  rbp
    push  rbx
    sub   rsp, $20              // 32 Byte müssten doch reichen?!
    mov   rbp, rsp
    call  wax_float_to_string
    add   rsp, $20
    pop   rbx
    pop   rbp

    push  rax

  @RETURN :
    mov   rsi, $01              // Teilfunktion war erfolgreich
    jmp   rbx                   // Springe zur aufrufenden Funktion zurück
end;


ausblenden 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..63of WideChar;
    len     : Integer;
    lVal    : TWax_Double;
begin
  lVal   := AValue;
  len    := FloatToText(lBuffer, lVal, fvExtended, ffGeneral, 150, WAX_FORMAT_SETTINGS); // >>> HIER ACCESS VIOLATION
  [...] 
end;



Fehlerstelle in GetBcdBytes:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25

Win7
Delphi XE2
BeitragVerfasst: 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
Hält's aus hier
Beiträge: 7



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25

Win7
Delphi XE2
BeitragVerfasst: 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.