![]() |
Re: Float-Parameter per ASM übergeben
Was erhältst du denn, wenn du das mal so aufrufst?
Delphi-Quellcode:
Edit: Syntax korrigiert
procedure TForm1.Aufruf(Params: array of const);
begin Test3(TVarRec(Params[0]).vExtended^); end; |
Re: Float-Parameter per ASM übergeben
Hi,
Dann funktionierts... :? Ach ja... diese riesen ShowMessage lässt sich auch nicht wegklicken... :shock: |
Re: Float-Parameter per ASM übergeben
Setze mal einen Haltepunkt auf den Anfang von Test3 und gehe dort in die CPU-Ansicht und schaue dir den Stack an. Wo ist der Unterschied zwischen den Aufrufen?
|
Re: Float-Parameter per ASM übergeben
Hi,
hier zwei Screenshots. (Das ist doch der Stack oder?) Der Stack bei normalem Aufruf:
Delphi-Quellcode:
procedure TForm1.ExecuteScriptMethod(Method: String;
Params: array of Const); begin Test3(Params[0].VExtended^); exit; // weiterer Code end; ![]() und wenn ichs über meine Methode aufrufe: (siehe Post weiter oben) ![]() Kann da jedoch nichts reininterpretieren... Gruß Neutral General |
Re: Float-Parameter per ASM übergeben
Ah, hier liegt eindeutig ein Alignment-Problem vor (ich kann allerdings nicht sagen, warum dass zu diesem seltsamen ShowMessage führt). Ich dachte, dass bei push word xyz automatisch auf ein DWord erweitert wird, anscheinend wird aber tatsächlich nur ein Word gepusht und ESP entsprechend nur um 2 verringert.
Ändere das mal so ab:
Delphi-Quellcode:
//statt
push word ptr [edx+$08] //das verwenden: movzx eax, word ptr [edx+$08] push eax |
Re: Float-Parameter per ASM übergeben
Hi,
Also du hast mir bisher sehr geholfen. Es tut mir Leid, aber ich muss nochmal weiter nachfragen :? :wall: Ich habe jetzt die "Float-Kompatibilität" auf die Parameter 3-n erweitert (bzw 4-n wenn man Self mitzählt), also die Parameter die auf dem Stack abgelegt werden. Jedoch kommt bei mir in der Funktion immer nur der Wert: -3,6854775808e-3509. Außerdem erhalte ich die Exception: "Ungültige Gleitkommaoperation in meiner Test4-Procedure:
Delphi-Quellcode:
Hab mir auch den Stack angeguckt: Ich glaube da ist diesesmal nichts verschoben, er sieht jetzt immer total anders aus...
procedure TForm1.Test4(b: Byte; S: String; f: Extended); //b und S sind nur damit f der dritte parameter sein kann
begin ShowMessage(S + ' ' + FloatToStrF(f,ffNumber,5,2) + IntToStr(b)); end; Hier der Code:
Delphi-Quellcode:
Apollonius... *hundeblick* :mrgreen:
procedure TForm1.ExecuteScriptMethod(Method: String;
Params: array of Const); var max,off: Integer; proc: Pointer; begin proc := MethodAddress(Method); max := Length(Params); for i:= 2 to max-1 do begin off := i*8; asm mov edx,[Params] add edx,off movzx ecx,[edx+$04] // Params[i].VType --> ecx sub ecx,3 // if Params[i].VType = vtExtended jnz @NoExt movzx ecx, word ptr [edx+$08] // then... push ecx push [edx+$04] push [edx] jmp @LoopEnd @NoExt: // else push [edx] @LoopEnd: end; end; // edx,ecx Parameter und eax = Self Parameter folgen end; |
Re: Float-Parameter per ASM übergeben
Du hast vergessen, den PExtended zu dereferenzieren. An den Anfang der Float-Behandlung muss noch ein mov edx, [edx].
|
Re: Float-Parameter per ASM übergeben
Zitat:
wird nicht hier beim pushen in einem dereferenziert
Delphi-Quellcode:
:?:
movzx ecx, word ptr [edx+$08]
push ecx push [edx+$04] push [edx] Wobei es trotzdem nicht funktioniert. (gleiches Problem wie vorher)
Delphi-Quellcode:
EDIT:
for i:= 2 to max-1 do
begin off := i*8; asm mov edx,[Params] add edx,off mov edx,[edx] // <--- hinzugefügt movzx ecx,[edx+$04] sub ecx,3 jnz @NoExt movzx ecx, word ptr [edx+$08] push ecx push [edx+$04] push [edx] jmp @LoopEnd @NoExt: push [edx] @LoopEnd: end; end; Wenn ich
Delphi-Quellcode:
durch
movzx ecx,[edx+$04]
Delphi-Quellcode:
ersetze, dann geht es o.O Warum das denn?
mov ecx,[Params]
add ecx,off add ecx,4 movzx ecx,[ecx] |
Re: Float-Parameter per ASM übergeben
Nach
Delphi-Quellcode:
Steht in edx ein Zeiger auf einen TVarRec. Folglich steht dann mit movzx ecx,[edx+$04] in ecx vType, wenn du kein mov edx,[edx] davor einfügst.
mov edx,[Params]
add edx,off Mit dem movzx ecx, word ptr [edx+$08] hast du dann allerdings in ecx schon den Anfang des nächsten TVarRec - schließlich zeigt edx auf einen, und SizeOf(TVarRec) ist 8. Wenn du allerdings davor noch ein mov edx, [edx] einfügst, zeigt edx nicht mehr auf den TVarRec, sondern auf den Extended, und dann stimmt alles. Du solltest das mov edx, [edx] also am besten direkt nach jnz @NoExt einfügen. Warum deine andere Lösung funktioniert, ist dann auch klar: Du hast zwar das mov edx, [edx] zu früh ausgeführt, aber um dir den vType zu holen, startest du von neuem und ignorierst den falschen Wert von edx. Allerdings wird es dann unangenehm für nicht-Floats. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:10 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz