![]() |
Frage zum Stack in Assembler
Hallo DPler!
Ich habe mir den Assembler Crashkur von [user]Balu der Bär[/user] angeschaut (sehr gutes Tutorial übrigens :thumb: ), aber bin beim rumprobieren auf ein Problem gestoßen (Ja, ich habe die Suche verwendet :wink: ) ich habe folgende Funktion:
Delphi-Quellcode:
Da ich aber gerne mehr über den Stack wissen würde, und folgendes Gilt
function Addiere4(A,B,C,D: integer): integer;
asm ADD EAX, B ADD EAX, C ADD EAX, D end;
Code:
müsste D ja auf dem Stack liegen, also sollte
EAX = A | EDX = B | ECX = C
Delphi-Quellcode:
doch auch funktionieren oder?
function Addiere4(A,B,C,D: integer): integer;
asm ADD EAX, B ADD EAX, C POP EDX ADD EAX, EDX end; Tuts aber nicht, ich kriege nur eine AV bei Adresse 0x00000000 ! Wo liegt mein Denkfehler? (ich dachte ich hätte es verstanden :cry: ) Gruß Richard |
Re: Frage zum Stack in Assembler
hast du dir mal im CPU Window vom Delphi angeschaut, wie deine Funktion aufgerufen wird?
Also, ob wirklich die variablen als Register übergeben werden, denn irgendwann gehen dir die registerplätze aus, und delphi muß dann die parameter per stack übergeben und nicht mehr per register. Also einfach mal nen Breakpoint zum aufruf deiner funktion und dann das cpu fenster einblenden, da müßtest sehen, wie die parameter übergeben werden. |
Re: Frage zum Stack in Assembler
Hmm... Was auch immer auf dem Stack liegt, es ist nicht D... ich übergebe die Zahl 4 und auf dem Stack liegt 1242668
Wie ist das denn dann mit dem Stack, komme ich, außer mit zb
Code:
nicht anders an D?
ADD EAX, D
|
Re: Frage zum Stack in Assembler
Ich hab jetzt nicht soviel Ahnung von ASM, aber so wie es aussieht, werden die ersten 3 Zahlen per Register übergeben und die letzte Zahl auf den stack gelegt...
Am anfang der Funktion wird och eine Adresse (Welche auch immer) auf den Stack gelegt... Dann beginnt das Rechnen... mit dem POP und holst du dir nun aber die Adresse die da hochgelegt wurde... Schlussendlich will er sich die auf dem Stack gelegte Adresse hollen, die ja nicht mehr da ist, da du diese ja gePOPed hast :zwinker: und bekommt deine 4te Zahl... Da springt er dann hin... Da da aber nicht das is was sein sollte, macht er kräftig aua... Ich hoffe das war so richtig :wink: Bye |
Re: Frage zum Stack in Assembler
POP ist immer falsch. Damit verschiebst du ja den Stackpointer und alles geht den Bach runter.
|
Re: Frage zum Stack in Assembler
Du Meinst der Holt Die Adresse, die er eigentlich braucht, um zurückzukehren vorher raus, und nimmt stattdessen meinen Wert von D als Rücksprungadresse?
Finde ich aber blöd, wäre es nicht sinnvoller, wenn er die Die Rücksprungadresse als erstes auf den Stack legt, schließlich handelt es sich ja um FIFO Zitat:
edit: So muss jetzt leider weg, werde nachher nochmal reinschauen |
Re: Frage zum Stack in Assembler
Zitat:
Zitat:
Zitat:
Wenn du jetzt wüsstest, dass der Wert von D auf dem Stack genau VOR der Zieladresse steht, kämst du mit zweimal POP dran. Müsstest dann aber die Zieladresse zurückschreiben. Also z.B. POP EDX POP ECX PUSH EDX Dann steht der Wert von vor der Rücksprungadresse auf ECX. Dann wäre aber natürlich der Wert von C weg. ;-) Ich denke aber nicht, dass das funktioniert. Weil vor der Rücksprungadresse liegen die alten Registerwerte. Direkt vor der Rücksprungadresse müsste also EPI liegt. Du müsstest also die ganzen alten Registerwerte erstmal weg- POPen und dann zurück. Wäre also recht sinnlos, vor allem, wo du nur 4 Register hast (ohne Speicherzugriffe). Hätte dann so ein wenig was von den Türmen von Hanoi. ;-) |
Re: Frage zum Stack in Assembler
Zitat:
Delphi-Quellcode:
bspw.
MOV EAX, [ESP + 12]
greetz Mike |
Re: Frage zum Stack in Assembler
Der Compiler von Delphi gestaltet den Funktionsaufruf recht unterschiedlich.
Dabei spielen folgende Kriterien eine Rolle -Ist die funktion vollständiger Assembler (beginnt gleich mit asm) -gibt es lokale Variablen (d gilt hierbei auch irgendwie als lokale Variable, da sie auf dem Stack liegt -wie sieht die Compilerdirektive aus ('stdcall', 'pascal' ,...) In deinem fall hast du Recht: Die ersten 3 Variablen liegen in den "veränderbaren Registern" (eax,edx,ecx), das sind quasi die Register, bei denen es (abgesehen von Variablenübergabe) egal ist, wie sie vor bzw. nach dem Funktionsaufruf aussehen. Alle anderen Variablen landen auf dem Stack (bei 'stdcall' landen immer alle Variablen auf dem Stack) Am besten immer im Einzelfall prüfen, was der Delphi-Compiler fabriziert. Was passiert noch? -also d wird auf den Stack gepusht -->d liegt bei [esp] -dann folgt der Funktionsaufruf mit Call (und Call legt gleich die Rücksprungadresse mit auf den Stack) -->also liegt d jetzt bei [esp+4]; zu Beginn der Funktion (der Compiler sieht lokale Variablen (d) auf dem Stack) rettet er sich noch schnell das EBP-Register (push ebp) und setzt dir freundlicherweise diesen Base-Pointer sozusagen als Referenz -->also liegt d jetzt bei [esp+8] bzw. bei [ebp+8] ===> übergebene Parameter liegen jetzt bei [ebp+8], [ebp+12],... lokale Variablen kannst du dir auf [ebp-4],[ebp-8],... legen. Solltest vorher aber noch den Stackpointer um die entsprechende Anzahl verschieben, falls du mal Register auf den Stack pushen willst oder aus deiner Funktion Call's tätigst. |
Re: Frage zum Stack in Assembler
Zitat:
Also hab ich das jetzt richtig verstanden: Die ersten drei Parameter landen in EAX, EDX und ECX Der Rest landet auf dem Stack, wobei Ganz oben auf dem Stack die Rücksprungadresse liegt, erst an DRITTER (?) Stelle (also +8 ) [EDIT: DER MACHT DA JA NEN SMILIE DRAUS, WENN ICH DA KEIN LEERZEICHEN EINFÜGE] des Stacks befindet sich der vierte Parameter der Funktion, ich kann ihn über [ebp+8 ] ansprechen Dieses Verhalten ist standardmäßig bei ein Funktion mit folgenden Eigenschaften 1. Es ist eine reine Assemblerfunktion 2. Sie hat mindestens 4 Parameter 3. Es gibt keine (?) lokalen variablen in der Funktion 4. Nochwas? edit: Diese blöden Quote tags... edit3: schon wieder diese tags... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:31 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 by Thomas Breitkreuz