faecher:informatik:oberstufe:techinf:assembler:beispiele1:start

section .data
     msg db 'Displaying 9 stars',0xa ;Message, Aneinanderreihung von "byte" (db) Bereichen
     len equ $ - msg  ;Laenge der Message
     s2  times 9 db '*' ; 9 x ein byte (db) mit dem Inhalt "*"
 
 
 section .text
    global _start     ;must be declared for linker
 
 _start:          ;startadresse
    mov  edx,len  ;Laenge nach edx
    mov  ecx,msg  ;Message nach ecx
    mov  ebx,1    ;file descriptor (stdout)
    mov  eax,4    ;system call number (sys_write)
    int  0x80     ;call kernel
 
    mov  edx,9    ;message length
    mov  ecx,s2   ;message to write
    mov  ebx,1    ;file descriptor (stdout)
    mov  eax,4    ;system call number (sys_write)
    int  0x80     ;call kernel
 
    mov  eax,1    ;system call number (sys_exit)
    int  0x80     ;call kernel

Hier kommt wieder der Linux-Systemaufruf 4 zum Einsatz. Linux-Systemaufrufe funktionieren grob folgendermaßen:

  • Lege die Nummer des Systemaufrufs in das EAX-Register
  • Speichere die Argumente für den Systemaufruf in den Registern EBX, ECX, usw.
  • Rufe den Interrupt (80h) auf
  • Das Ergebnis des Systemaufrufs wird normalerweise im EAX-Register zurückgegeben.

Um das erfolgreich zum Einsatz zu bringen, muss man wissen, was ein Systemaufruf in welchem Register erwartet, damit er funktioniert, beim System-Call 4 (Write) ist es folgendermaßen:

Name %eax %ebx %ecx %edx %esx %edi
Write 4 unsigned int (Output Stream) const char * (Inhalte) size_t (Länge) - -

Das kann man sich ein wenig wie eine Funktion/Methode mit Argumenten vorstellen: Man befüllt zunächst die Register mit den Argumenten und ruft dann den Systemaufruf auf.


(A1)

  • Gib 12 Sterne aus
  • Gib 4 Sterne aus
  • Sorge dafür, dass das Eingabeprompt in der Zeile unter den Sternen angezeigt wird

Weitere System-Calls:

Name %eax %ebx %ecx %edx %esx %edi
Exit 1 int (Exit Code) - - - -
Fork 2 struct pt_regs - - - -
Read 3 unsigned int char * size_t - -
Write 4 unsigned int (Output Stream) const char * (Inhalte) size_t (Länge) - -
Open 5 const char * int int - -
Close 6 unsigned int - - - -

Mit dem Sys-Call 3 lässt sich also eine Eingabe realisieren - "Read".

Damit das funktioniert muss man mehrere Dinge beachten:

  • Man benötigt einen reservierten, beschreibbaren Speicherbereich im .bss-Abschnitt des Programms
  • Ins Register eax muss der Wert 3 geschrieben werden
  • Ins Regsiter ebx muss der Filedescriptor, von dem gelesen werden soll. Wenn man das in einer Shell ausführt: 0, 1 oder 2.
  • Ins Register ecx muss die Adresse des in .bss reservierten Bereichs
  • Ins Register edx muss die Länge der zu lesenden Informationen
  • Dann wird der Syscall durch den Interrupt 0x80 ausgelöst
section .data                           ;.data Abschnitt
    userMsg db 'Bitte Zahl eingeben: ' ; Eingabeprompt
    lenUserMsg equ $-userMsg           ; Laenge 
    dispMsg db 'Du hast die folgende Zahl eingegeben: '    ; Ausgabeprompt
    lenDispMsg equ $-dispMsg           ; Laenge      
 
 
 
section .bss           ; Beschreibbarer Speicher, vobelegt mit 0-en
    antwort resb 5      ; 5 Byte 
 
 section .text          ; coe Abschnitt
    global _start
 
 _start:
 
    ;User prompt ausgeben
    mov eax, 4
    mov ebx, 0
    mov ecx, userMsg
    mov edx, lenUserMsg
    int 80h
 
    ;Neu: Benutzereingabe lesen
    mov eax, 3       ; syscall Nummer: 3
    mov ebx, 0       ; lesen von stdin
    mov ecx, antwort  ; antwort adresse in ecx
    mov edx, 5        ; 5 bytes lang
    int 80h           ; Syscall!
 
    ;Ausgabe
    mov eax, 4
    mov ebx, 0
    mov ecx, dispMsg
    mov edx, lenDispMsg
    int 80h
 
    ;Ausgabe der eingegebenen Zahl
    mov eax, 4
    mov ebx, 0
    mov ecx, antwort
    mov edx, 5
    int 80h
 
    ; Exit code
    mov eax, 1
    mov ebx, 0
    int 80h

(A2)

Übersetze und teste das Programm. Was passiert, wenn man weniger/mehr als 5 Ziffern eingibt? Beobachte genau.

  • faecher/informatik/oberstufe/techinf/assembler/beispiele1/start.txt
  • Zuletzt geändert: 14.09.2021 06:30
  • von sbel