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...


Log in to reply