Autor |
Beitrag |
Silas
      
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Mo 12.05.08 19:08
Hallo!
Ich hab mal wieder ein (eigenartiges) Problem.
Mein Code funktionierte bis vor Kurzem einwandfrei, aber jetzt spielt er verrückt:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure Bin2Hex(Source: Pointer; Length: Cardinal; Dest: PChar; Uppercase: Boolean); assembler; procedure Bin2Hex(Source: Pointer; Length: Cardinal; Dest: PChar; Uppercase: Boolean); asm push ebx mov bl, 10h mov esi, Source mov ecx, Length mov edi, Dest mov al, UpperCase test al, al jz @lc pop ebx end; |
Der Code an sich dürfte klar sein; Source, Length und Dest werden in ihre Register geschrieben.
Da liegt jetzt das Problem: Sowohl ecx als auch edi erhalten den Wert von Length. Wenn ich das Ganze umdrehe, erhalten beide den Wert von Dest.  (Ja, sie haben den Wert nachher wirklich, das liegt nicht am Debugger. Die Werte stehen zumindest in der AV  )
Wenn ich statt diesem den auskommentierten Code verwende, funktioniert alles einwandfrei.
Was ist da los?  Hat das evtl. etwas mit der assembler-Direktive oder der Parameterübergabe zu tun (kein const / var)? Sollte man bei reinen Assemblerfunktionen eine andere Aufrufkonvention verwenden?
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mo 12.05.08 19:45
Die Angabe Assembler wird von Delphi ignoriert, da sie nicht nötig ist.
Zu deinem Problem: Nur EAX, EDX und ECX sind frei verfügbar. Jegliche andren Register (EBX, EDI, ESI) müssen gesichert und wiederhergestellt werden.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Silas 
      
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Mo 12.05.08 20:27
BenBE hat folgendes geschrieben: | Die Angabe Assembler wird von Delphi ignoriert, da sie nicht nötig ist. |
Oh, hätte gedacht sie wäre nötig, wenn die Prozedur keinen begin- end-Block hat. Man lernt nie aus  .
BenBE hat folgendes geschrieben: | Zu deinem Problem: Nur EAX, EDX und ECX sind frei verfügbar. Jegliche andren Register (EBX, EDI, ESI) müssen gesichert und wiederhergestellt werden. |
Bei EBX wusste ich das, die Indexregister haben mir bis jetzt nie Probleme bereitet. Das Sichern ändert auch nichts am Problem (das ja (auch laut Debugger) bei der Zuweisung besteht). 
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mo 12.05.08 20:44
ESI und EDI werden für OOP bei Delphi genutzt (glaub ESI war der Self-Pointer, EDI die Klassen-Referenz). Wenn Du die also in deiner Routine änderst, ...
Ferner solltest Du beachten, was Du in den ersten Zeilen geschrieben hast (Vergleich mal mit dem CPU-Fenster  ):
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure Bin2Hex(Source: Pointer; Length: Cardinal; Dest: PChar; Uppercase: Boolean); assembler; procedure Bin2Hex(Source: Pointer; Length: Cardinal; Dest: PChar; Uppercase: Boolean); asm push ebx mov bl, 10h mov esi, EAX mov ecx, EDX mov edi, ECX mov al, BYTE PTR [ESP+4] test al, al jz @lc pop ebx end; |
Merk Dir am Besten die Zuordnung der Register für die Register-Aufruf-Konvention und arbeite damit. Ist IMMER EAX, EDX, ECX und der Rest Stack, zugeordnet von Links nach Rechts.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Silas 
      
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Mo 12.05.08 21:11
BenBE hat folgendes geschrieben: | ESI und EDI werden für OOP bei Delphi genutzt (glaub ESI war der Self-Pointer, EDI die Klassen-Referenz). Wenn Du die also in deiner Routine änderst, ... |
Gut, meine Funktionen sind global, insofern ist es in dem Fall egal. Werds mir aber merken, danke für den Tip  .
BenBE hat folgendes geschrieben: | Ferner solltest Du beachten, was Du in den ersten Zeilen geschrieben hast (Vergleich mal mit dem CPU-Fenster ):
...
Merk Dir am Besten die Zuordnung der Register für die Register-Aufruf-Konvention und arbeite damit. Ist IMMER EAX, EDX, ECX und der Rest Stack, zugeordnet von Links nach Rechts. |  Oha. Wusste nicht, dass Delphi ohne explizite register-Direktive die Register an Stelle des Stacks verwendet. Man gewöhnt sich so schnell an MASM...
Beim rumprobieren ist mir aufgefallen, dass sich das Problem mit stdcall lösen lässt, ich wusste nur nicht warum. Dann dreh ich die Zuweisungen mal ein wenig um  .
Danke für die Hilfe!
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mo 12.05.08 21:22
Silas hat folgendes geschrieben: | BenBE hat folgendes geschrieben: | ESI und EDI werden für OOP bei Delphi genutzt (glaub ESI war der Self-Pointer, EDI die Klassen-Referenz). Wenn Du die also in deiner Routine änderst, ... | Gut, meine Funktionen sind global, insofern ist es in dem Fall egal. Werds mir aber merken, danke für den Tip .
BenBE hat folgendes geschrieben: | Ferner solltest Du beachten, was Du in den ersten Zeilen geschrieben hast (Vergleich mal mit dem CPU-Fenster ):
...
Merk Dir am Besten die Zuordnung der Register für die Register-Aufruf-Konvention und arbeite damit. Ist IMMER EAX, EDX, ECX und der Rest Stack, zugeordnet von Links nach Rechts. | Oha. Wusste nicht, dass Delphi ohne explizite register-Direktive die Register an Stelle des Stacks verwendet. Man gewöhnt sich so schnell an MASM...
Beim rumprobieren ist mir aufgefallen, dass sich das Problem mit stdcall lösen lässt, ich wusste nur nicht warum. Dann dreh ich die Zuweisungen mal ein wenig um .
Danke für die Hilfe! |
Bei STDCall funkzt es, weil stdcall für alles den Stack (von Rechts nach Links) nutzt ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Silas 
      
Beiträge: 478
Windows XP Home
Delphi 2005, RAD Studio 2007, MASM32, FASM, SharpDevelop 3.0
|
Verfasst: Mo 12.05.08 21:38
BenBE hat folgendes geschrieben: | Bei STDCall funkzt es, weil stdcall für alles den Stack (von Rechts nach Links) nutzt ... |
Weiß ich, ich hatte mich nur darüber gewundert, weil ich davon ausgegangen bin, dass das Problem - nachdem es ja mit stdcall funzt - damit zusammenhängt, dass die Pascal-Konvention "falschherum" arbeitet. 
_________________ Religionskriege sind nur Streitigkeiten darüber, wer den cooleren imaginären Freund hat
|
|
|