Speichergröße von Registern
-
Hallo, ich beziehe mich hier auf folgendes Tutorial für den GNU Assembler: http://www.m-hoeppner.de/projects/asm_ws.pdf
Register sind kleine Datenspeicher innerhalb des Prozessors. Bei 32 Bit
Prozessoren sind die Register je 32 Bit (ein Word) groß, also wesentlich
kleiner als der RAM aber dafür auch sehr viel schneller.und
Die einfachste Methode ist der sog. Immediate Mode, indem die Daten in der
Anweisung selbst eingebettet sind. D. h. man sagt nicht "lege den Wert an
Adresse blabla ins Register eax", sondern "lege den Wert 34 ins Register eax".
In diesem Fall erwartet der Assembler, dass wir ein Dollarzeichen ('$') vor den
Wert schreiben.Nachdem ich das gelesen habe fiel mir im Hallo Welt example etwas merkwürdiges auf.
.section .data hello: .ascii "Hello World!\n" .section .text .globl _start _start: mov $4, %eax # 4 fuer den Syscall 'write' mov $1, %ebx # File Descriptor mov $hello, %ecx # Speicheradresse des Textes mov $13, %edx # Laenge des Textes int $0x80 # und los mov $1, %eax # das mov $0, %ebx # uebliche int $0x80 # beenden
---------------------------------
Mit Bezug auf Zeile 8:
Laut voriger Aussage wird durch $ ein Wert in das Register geschrieben. Ein ASCII-Zeichen belegt 1 Byte, somit würden in ecx maximal 4 ASCII Zeichen passen. Wird tatsächlich nur die Speicheradresse von hello übergeben? Das stünde im Gegensatz zur Aussage, dass mit $ die Werte direkt ins Register geschrieben werden. Ich bin etwas verwirrt.
-
@TheQ: Du musst es wie folgt sehen. Die folgende Zeile:
hello: .ascii "Hello World!\n"
bedeutet, es gibt irgendwo im Speicher an einer bestimmten Adresse einen String und überall in deinem Code wird beim Linken hello durch eine Zahl ersetzt (z.B. 0x12345678), die dieser Adresse entspricht.
Die folgenden beiden Befehle:movl hello, %eax movl $hello, %eax
werden z.B. wie folgt übersetzt:
movl 0x12345678, %eax movl $0x12345678, %eax
Die Syntax des Assemblers legt fest: Das $-Zeichen dient der Unterscheidung zwischen Konstanten und Adressen. Konstanten bekommen das $-Zeichen, Adressen bekommen keins.
Mit diesem Befehl werden irgendwelchhe Daten an der Adresse 0x12345678 gelesen. eax enthält danach irgendwas, was zufällig im Speicher an der Adresse 0x12345678 steht (vorausgesetzt natürlich, dein Prozess darf auf die Adresse zugreifen, sonst gibt es einen SIGSEG, segmentation fault, und dein Prozess wird gekillt):
movl 0x12345678, %eax
Mit diesem Befehl wird die Konstante (weil $-Zeichen) 0x12345678 in das Register eax geladen. eax ist danach gleich 0x12345678:
movl $0x12345678, %eax
Analog mit dem hello:
Mit diesem Befehl werden Daten an der Adresse hello gelesen. eax enthält danach das, was im Speicher an der Adresse hello steht, eax = "lleH" (nicht "Hell", x86 sind Little Endian):
movl hello, %eax
Mit diesem Befehl wird die Konstante, die beim Linken hello ersetzt, ins Register eax geladen. eax enthält danach die Adresse des Strings:
movl $hello, %eax
Hoffe, hab keine Fehler gemacht...