Eine kleine Einführung in Assembler
Assembler ist eine der am einfachsten aufgebauten Sprachen die mit bekannt sind.
Denn es ist nichts anderes als die oben genannten Instruktionen für einen Menschen lesbar aufgeschrieben.
Es kann dir helfen den Code noch besser zu verstehen, da sie ja die kleinsten Bestandteile des Codes sind.
Wir werden x86 Assembler behandeln. Ich werde vielleicht ein Tutorial machen was an diesen Teil des Tutorials anschließt.
Falls irgendjemand so etwas interessiert kann er ja einen Kommentar da lassen.
Syntax:
Assembler hat eine sehr einfach Syntax
Es hat viele Ähnlichkeiten mit AutoHotkey Befehlen.
Es besteht aus der Instruktion auf die dann ihre Parameter folgen:
Beispiel:
Parameter?
Parameter sind Informationen welche Informationen die Instruktion erhalten soll und wo sie ihren output hin loswerden soll. Der erste Parameter erhält immer das Ergebnis, gibt aber oft auch gleichzeitig Input.
Als Input können viele Register, Memory Adressen oder ganz normale Zahlen verwendet werden.
Als Output kommen nur Memory Adressen oder Register in Frage.
Der erste Parameter ist meistens der Ziel Parameter der den Output der Instruktion erhalten soll, falls es denn welchen gibt:
Code: Select all
MOV EAX,EBX ;kopiert den Inhalt von EBX in EAX
ADD EAX,EBX ;addiert EAX zu EBX und peichert das Ergebnis in EAX
MOV EAX,[0x1000] ;Lade den Wert der bei der Memory Adresse 0x1000 gespeichert
ADD EAX,1000 ;addiert 1000 zu EAX und speichert das Ergebnis in EAX
MOV [0x1000],EAX ;speichert EAX in der Speicher Adresse 0x1000
Code: Select all
Addtoavar:
ADD [0x1000],1000 ; Macht das selbe wie die letzten 3 Instruktionen aus dem letzten Beispiel-
Die
CALL Instruktion kommt mir einem Helfer der
RET Instruktion.
Wenn die
CALL Instruktion ausgeführt wird springt die CPU zu der Ziel Adresse und führt den Code der sich dort befindet aus. Die RET Instruktion springt wieder zu der Position zurück wo die letzte
CALL Instruktion ausgeführt wurde (return).
Der Stack
Es gibt einen speziellen Ort im Speicher den Programme nutzen können und auf den sie über Instruktionen gesondert zugreifen können. Stack bedeutet übersetzt so viel wie Stapel. Und genau so beschreibt man diesen Ort am besten auch. Er stapelt binäre Informationen. Du kannst etwas oben auf den Stack legen und es dann lesen, auch wenn noch etwas oben auf den Stack gelegt wird. Entfernen kannst du aber nur von dem oberen Ende des Stacks.
Den Stack findet man am Ende der Adressen Reichwiete:
Bei 32 bit fängt er bei der höchst möglichen Zahl (Nach unseren bisherigen Informationen theoretisch 0xFFFFFFFF) an und zählt dann runter. Wenn man zum Beispiel 4 bytes auf den Stapel legen würde er den sogenannten Stackpointer um 4 reduzieren (dann theoretisch 0xFFFFFFFA).
Wenn nun die 4 bytes wieder entfernt werden, wird der Stackpointer um 4 erhöht.
Es gibt ein Register welches nur die Aufgabe hat den Stackpointer zu halten - das ESP Register.(Extended Stack Pointer Register)
Man kann neue Informationen über die
Push Instruktion zu dem Stack hinzufügen. Und per
Pop Informationen von dem Stack entfernen.
Code: Select all
PUSH a ;was auch immer ihr als a haben wollt (Speicheradresse oder ein Register)
POP EAX ;tut das auf den Stack geschobene a in EAX und entfernt es davon,entfernt.
Man kann auf den Stack auch über eine
MOV Instruktion zugreifen:
Code: Select all
MOV EAX,[ESP] ;Greife auf den Wert zu der oben auf dem Stack gespeichert ist und lege ihn in EAX
MOV [ESP],EAX ;Lege den Wert von EAX in den Wert der am Ende des Stacks gespeichert ist
Wenn man per
Call eine Funktion aufruft, legt die
Call Instruktion die Adresse der nächsten Instruktion die auf die Call Instruktion folgt auf den Stack.
Ret hingegen nimmt die oberste auf dem Stack liegende Information und springt zu dieser Adresse zurück.