Entwickler-Ecke
Windows API - Assembler
.Johannes. - Mo 05.01.04 14:50
Titel: Assembler
Hi!
Ich habe folgende Funktion eingebaut:
Delphi-Quelltext
1: 2: 3: 4: 5:
| function MessageBox ( HWnd: Integer; Text, Caption: PChar; Flags: Integer ): Integer; stdcall; external 'user32.dll' name 'MessageBoxA'; |
Nun habe ich zwei Strings: Text und Titel.
Jetzt kann ich mit "Messagebox (0,Text,Titel,0);" die Message anzeigen.
wenn ich es aber in Assembler versuche mit:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| asm push 0 push offset Text push offset Titel push 0 call Messagebox end; |
dann fliege ich aus dem Programm raus, mit dem Hinweis auf irgendeine Zugriffsverletzung.
Moderiert von
Motzi: Delphi-Tags hinzugefügt
Anonymous - Mo 05.01.04 15:03
Probier es mal so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| var a,b: string; begin a := 'foo'; b := 'bar'; asm push 0 lea eax,a call UniqueString push eax lea eax,b call UniqueString push eax push 0 call MessageBox end; end; |
Motzi - Mo 05.01.04 18:33
Ein Auruf von UniqueString ist an dieser Stelle unnötig..! Man muss halt bei dem ganzen bedenken, dass Delphi-Strings (zumindest die Ansi-Strings) eigentlich auch nur Pointer sind...
Anonymous - Mo 05.01.04 19:38
Eben nicht. Nach dem Aufruf von Uniquestring befindet sich in eax die Speicheradresse des ersten Buchstabens in a/b. (=> entspricht PChar)
Die Speicheradresse der Variablen entspricht aber nicht PChar, wodurch es zu einer AE kommt.
Motzi - So 11.01.04 23:06
| obbschtkuche hat folgendes geschrieben: |
Eben nicht. Nach dem Aufruf von Uniquestring befindet sich in eax die Speicheradresse des ersten Buchstabens in a/b. (=> entspricht PChar)
Die Speicheradresse der Variablen entspricht aber nicht PChar, wodurch es zu einer AE kommt. |
Oops.. hab den Thread damals ganze vergessen.. das kommt davon wenn man nicht auf seine Emails zugreifen kann.. :?
UniqueString sorgt dafür, dass der String in einen neuen Speicherbereich kopiert wird und der Referenzzähler auf 1 gesetzt wird. Das ist bei APIs notwendig die Daten im übergeben String ablegen, denn wenn mehrere Strings dieselbe Zeichenkette referenzieren (Referenzzäher > 1), dann werden alle diese Strings von einer Änderung beeinflusst!
Probier mal folgenden Aufruf:
Delphi-Quelltext
1: 2: 3: 4: 5:
| var s: String;
s := 'Test'; MessageBox(Pointer(s), Pointer(s), 0); |
und schau mal was der Compiler daraus macht... was für eine Überraschung, er pusht nur die Adresse auf die der String s zeigt, denn ein Delphi-String ist bereits ein Zeiger auf eine Zeichenkette, so wie ein PChar! ;)
Ich bin gerade dabei ein Tutorial über Strings, die String-Internals und alles möglicher rundherum zu schreiben... da steht das auch in allen Details drinnen beschrieben...!
Anonymous - Mo 12.01.04 17:03
oh, interessant... da wundert mich aber, was der compiler aus
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| var s: String; begin s := 'Test'; MessageBox(0, pchar(s), pchar(s), 0); end; |
macht. Und da erstaunt mich auch der Unterschied zwischen @s und @s[1]. Eigentlich ist @s[1] dann ja der pchar...
Motzi - Mo 12.01.04 20:27
Ja... es gibt 3 Möglichkeiten auf PChar zu casten:
PChar(String)
@String[1]
Pointer(String)
und jede dieser Möglichkeiten wird vom Compiler anders umgesetzt... aber die Details dazu stehen alle in meinem Tutorial, welches ich hoffentlich eh in Kürze veröffentlichen kann...
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 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!