Montageproblem mit einfachem Programm
-
29-09-2019 - |
Frage
Ich versuche, Montage von Grund auf zu lernen. Ich habe gelesen, bis ziemlich viel, aber auch das folgende einfache Programm, das ich in einem Referenzbuch gefunden hat mich ratlos:
section .data
msg db "Hello!", 0xa
len equ $ - msg
section .text
global _start
_start:
move edx, len
move ecx, msg
move ebx, 1
move eax, 4
int 0x80
move ebx, 0
move eax, 1
int 0x80
Nun ist offenbar das soll „Hallo“ drucken. Aber ich weiß nicht einmal, was sich in einem der Stadien geschieht. Die ersten beiden Stufen stellen die Nachrichtenlänge und messgae in zwei Registern, die nie wieder verwendet werden. Ich verstehe nicht, warum.
Ich weiß nicht, warum vier verschiedene Register benötigt werden.
Lösung
int 80
ist ein Mechanismus in einigen * a UNIX-ähnliche Systeme für die Herstellung von Systemaufrufen betrieben wird.
Für diese Anrufe werden die Register für bestimmte Werte verwendet. Von der syscalls
-Datei:
0 STD NOHIDE { int nosys(void); } syscall nosys_args int
1 STD NOHIDE { void exit(int rval); } exit rexit_args void
2 STD POSIX { int fork(void); }
3 STD POSIX { ssize_t read(int fd, void *buf, size_t nbyte); }
4 STD POSIX { ssize_t write(int fd, const void *buf, size_t nbyte); }
Sie können sehen, dass Nummer 4 der write
Anruf und muss drei weitere Parameter. Die Nummer 1 ist exit
und muss nur den Return-Code.
Wenn der Anruf, eax
ist die syscall, dass Sie machen, während ebx
, ecx
und edx
sind die drei Parameter (vorausgesetzt, sie sind alle benötigten - exit
zum Beispiel braucht nur eine).
So können Sie den Code wie folgt Stellung:
move edx, len ; length of message (nbyte).
move ecx, msg ; message to print (buf).
move ebx, 1 ; file handle 1, stdout (fd).
move eax, 4 ; write syscall.
int 0x80 ; do it.
move ebx, 0 ; exit code (rval).
move eax, 1 ; exit syscall.
int 0x80 ; do it.
* a: Spätere Versionen von Linux eingeführt, um die eine neue Schnittstelle, die verschiedene Methoden auf dessen Basis die beste Geschwindigkeit nutzen können. Zum Beispiel sind einige Intel-Chips viel schneller, wenn Sie sysenter
statt int 80
verwenden.
Andere Tipps
IIRC die int 0x80
Anweisung wird verwendet, um einen Systemaufruf aufzurufen durch den Interrupt-Vektor verwendet wird. In Ihrem Beispiel werden die Werte in ebx
und eax
verwendet, die angeben SYSCALL Sie gehend zu nennen (wahrscheinlich der Druckvorgang auf stdout) sind.
Der syscall weiß durch Konvektion, dass edx
und ecx
enthalten sollten, was gedruckt Gonna werden soll.
Auf vielen Systemen int 80h ist die Systemaufruf Tor. Die syscall Zahl ist in eax
. ebx
, ecx
und edx
enthalten zusätzliche Parameter:
move edx, len
move ecx, msg
move ebx, 1 ; fd 1 is stdout
move eax, 4 ; syscall 4 is write
int 0x80 ; write(1, msg, len)
move ebx, 0
move eax, 1 ; syscall 1 is exit
int 0x80 ; exit(0)
Wenn Sie einen Systemaufruf rufen, die ‚int‘ mnemonic wird eine Systemunterbrechung erzeugt. Es irgendwie „springt“ auf eine Systemfunktion, die in diesem Fall druckt Ausgabe (abhängig von EAX).
Diese Unterbrechung nutzt all diese Register zu wissen, was zu tun ist. Der Interrupt liest eax, zu überprüfen, was funktioniert, wie Sie wollen, und verwendet die anderen Register, dies zu tun.
eax ist die Funktionsnummer, 4 Mittel sys_write, die einen String in einen Stream / Dateideskriptors schreibt.
Jetzt ist es weiß, dass Sie an einen Ort zu etwas schreiben wollen, dann ist es die anderen Register auf diese Informationen verwendet.
für EAX = 4 und int 0x80 dies ist die Bedeutung für die anderen Register:
ebx = Ausgang (1 = stdout)
ECX = Adresse des Strings
edx = Länge der Zeichenfolge
Sie können diese Zeilen lesen:
http://www.intel.com/Assets/ja_JP/ PDF / manual / 253665.pdf
Abschnitt 6.4 Es hat ein paar Sachen über Interruptins und Ausnahmen.
Und Sie beginnen Intel 80x86 Assembler-Code zu schreiben, die einfacher und leichter zu verstehen ist, sind hier einige Links:
Mnemonics / Code Tabellen Spickzettel: http://www.jegerlehner.ch/intel/
Einige Einleitungsstellen: http://mysite.du.edu/~etuttle/math/8086.htm http://www.malware.org/teaching/assembly.htm