Wie Sie eine assembly-Sprache funktioniert?
Ich Lerne Montage und ich habe diesen Assembler-code, und mit viel Mühe ihn zu verstehen, kann jemand erläutern?
Dump of assembler code for function main:
0x080483ed <+0>: push ebp
0x080483ee <+1>: mov ebp,esp
0x080483f0 <+3>: sub esp,0x10
0x080483f3 <+6>: mov DWORD PTR [ebp-0x8],0x0
0x080483fa <+13>: mov eax,DWORD PTR [ebp-0x8]
0x080483fd <+16>: add eax,0x1
0x08048400 <+19>: mov DWORD PTR [ebp-0x4],eax
0x08048403 <+22>: leave
0x08048404 <+23>: ret
Bis jetzt meine verstanden zu wissen, ist die folgende:
Drücken etwas (weiß nicht was) in ebp
registrieren. dann verschieben Sie Inhalte von esp
registrieren Sie sich in ebp
(ich denke, die Daten von ebp
überschrieben werden soll), dann subtrahieren 10 von der esp
und speichern Sie es in den esp
(Die Funktion 10 byte, Das reg wird nie wieder verwendet, also kein Punkt, dies zu tun-Betrieb). Nun weisen Sie den Wert 0 an die Adresse, die Spitzen von 8 bytes weniger als ebp
.
Nun speichern Sie diese Adresse in register eax
. Nun fügen Sie 1 auf den Wert hingewiesen, die von eax
(der Vorherige Wert verloren). Nun speichern Sie die eax
Wert auf [ebp-0x4]
, dann verlassen, um die Rückkehr-Adresse main
.
Hier ist mein C-code für das obige Programm:
int main(){
int x=0;
int y = x+1;
}
Nun, kann jemand herausfinden, wenn ich falsch bin nichts,und ich versteh auch nicht, der mov
at <+13> es addiert 1, um die addrs ebp-0x8
, aber das ist die Adresse von int x
so x
nicht mehr 0 enthalten. Wo bin ich falsch?
- Warum nicht abholen eine Anleitung zum Zusammenbau?
push ebp
nicht schieben etwas inebp
es wird der aktuelleebp
Inhalt auf dem Stapel, so dass Sie später wiederhergestellt werden. - Nehmen Sie ein Lesen Sie hier: en.wikibooks.org/wiki/X86_Disassembly/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
zunächst
push ebp
und dannmov ebp, esp
sind zwei Anweisungen, die Häufig am Anfang einer Prozedur. ESP-register ist ein Indikator für die Spitze des stack - also es ändert sich ständig, wie der Stapel wächst oder schrumpft. EBP ist eine helfende registrieren Sie sich hier. Zuerst schieben wir Inhalt von ebp auf dem stack. dann kopieren wir ESP (aktuelle stack top Adresse) zu ebp - das ist, warum, wenn wir auf andere Elemente auf dem stack verwenden wir Konstanten Wert von ebp (und nicht das wechseln des esp).nun für den echten Spaß:
Hoffe, das hilft! 🙂
(0x10 is 32 in hex)
Sind Sie sicher?sub esp, 0x10
,, dieser Befehl weder etwas, noch ist es später benötigt, und die zweite Frage ist, die Register enthalten nicht nur die Adresse.Es können Werte enthalten auch? wie inadd eax,0x1
?sub esp 0x10
verpasst die top-of-the-stack-pointer. Die grundlegende Regel, die Sie haben zu erinnern ist, dass "Der stack wächst in Richtung niedriger Adressen" - also durch Subtraktion 16 aus dem Stapel, den du eigentlich behalten 16 Byte auf dem stack (dies ermöglicht es Ihnen zu schreiben x und y gibt es zwei 32-bit-Sequenzen)main()
anrufen konnte, werden auf den stack geschoben, ohne es zu überschreiben/Kollision mitx
undy
. Sie sind richtig in der Beobachtung ist die nicht wirklich benötigt/verwendet. Einige Register sind speziell zum halten von Zeigern (z.B. "sp" steht für stack-pointer, während einige sind die Allgemeinen Zwecke und kann Daten enthalten oder Zeiger); einige Montage-Anweisungen ermöglichen die Verwendung von Daten, Zeiger und Zähler nur, wenn Sie im Register unterstützt.ebp, esp
- pair ist keine Einschränkung per se, so kann der code-Adresse einen beliebigen Wert es will. Dabei wird normalerweise ein Puffer-überlauf-Fehler oder eine Beschädigung von stapeln wenn. So Ihr Verständnis, dass die Funktion kann nicht über esp-10x falsch ist und Sie sollten nicht denken, dass es als solche. Es SOLLTE nicht darüber hinaus.Aufbau der Stapel-Rahmen. Speichern Sie die alte base pointer und legen Sie die oben auf dem Stapel, als der neue base-pointer. Dies ermöglicht es, dass lokale Variablen und Argumente innerhalb dieser Funktion verwiesen werden, die relativ zu
ebp
(base pointer). Dies hat den Vorteil, dass Ihr Wert stabil ist im Gegensatz zu esp, die betroffen ist durchpush
es undpop
s.Auf der x86-Plattform der stack wächst nach unten. Im Allgemeinen bedeutet dies
esp
hat einen niedrigeren Wert (Adresse im Speicher) alsebp
. Wennebp == esp
hat der Stapel nicht reserviert Speicher für die lokalen Variablen. Dies bedeutet nicht, es ist "leer" - eine gemeinsame Nutzung des Stacks ist[ebp+0x8]
zum Beispiel. In diesem Fall der code ist auf der Suche nach etwas auf dem stack, die vorher geschoben, auf die vor dem Aufruf (dies könnte man Argumente in derstdcall
Konvention).In diesem Fall wird der stack erweitert von 16 bytes. In diesem Fall wird mehr Speicherplatz reserviert wird als notwendig für Ausrichtung Zwecke:
Die 4 bytes an
[ebp-0x8]
initialisiert werden auf den Wert 0. Dies ist Ihrex
lokale variable.Die 4 bytes an
[ebp-0x8]
verschoben werden, zu einem register. Arithmetische Befehle nicht bedienen können mit zwei speicheroperanden. Daten müssen bewegt werden, um eine sich zuerst registrieren, bevor die Arithmetik durchgeführt wird.eax
enthält jetzt den Wert Ihresx
variable.Den Wert
eax
ist erhöht, damit es hält nun den Wertx + 1
.Speichert den berechneten Wert zurück auf den stack. Beachten Sie die lokalen Variablen ist nun
[ebp-0x4]
- das ist Ihry
variable.Zerstört den stack frame. Im wesentlichen maps für
pop ebp
und wieder der alte stack base pointer.Erscheint der stack-Spitze, die Behandlung der Wert als eine Rückkehr-Adresse und setzt den Programm-Zeiger (
eip
) auf diesen Wert. Die Adresse zurück, die in der Regel enthält die Adresse der Anweisung, die direkt nach dercall
Unterricht brachte, dass die Ausführung in dieser Funktion.