TI2/Rechnerarchitektur-Tutorium, 12.01.2017

Nachbesprechung

Stack 1

   10: CALL f
   11:









+-------------------+ <- RSP (9920)
| Variablen (80 B)  |
+-------------------+ <- RBP (1000)
| Rücksprungadresse |
+-------------------+

Stack 2

=> 10: CALL f
   11:







+-------------------+ <- RSP (9912)
| Rückspr.-Addr: 11 |
+-------------------+
| Variablen (80 B)  |
+-------------------+ <- RBP (1000)
| Rücksprungadresse |
+-------------------+

Stack 3

 f:
=> 20: PUSH RBP             23: MOV RSP, RBP
   21: MOV RBP, RSP         24: POP RBP
   22: Beliebige PUSHs      25: RET



+-------------------+ <- RSP (9904)
| alter RBP: 10000  |
+-------------------+
| Rückspr.-Addr: 11 |
+-------------------+
| Variablen (80 B)  |
+-------------------+ <- RBP (1000)
| Rücksprungadresse |
+-------------------+

Stack 4

 f:
   20: PUSH RBP             23: MOV RSP, RBP
=> 21: MOV RBP, RSP         24: POP RBP
   22: Beliebige PUSHs      25: RET



+-------------------+ <- RSP (9904), RBP (9904)
| alter RBP: 10000  |
+-------------------+
| Rückspr.-Addr: 11 |
+-------------------+
| Variablen (80 B)  |
+-------------------+
| Rücksprungadresse |
+-------------------+

Stack 5

 f:
   20: PUSH RBP             23: MOV RSP, RBP
   21: MOV RBP, RSP         24: POP RBP
=> 22: Beliebige PUSHs      25: RET

+-------------------+ <- RSP (9744)
| Variablen (160 B) |
+-------------------+ <- RBP (9904)
| alter RBP: 10000  |
+-------------------+
| Rückspr.-Addr: 11 |
+-------------------+
| Variablen (80 B)  |
+-------------------+
| Rücksprungadresse |
+-------------------+

Stack 6

 f:
   20: PUSH RBP          => 23: MOV RSP, RBP
   21: MOV RBP, RSP         24: POP RBP
   22: Beliebige PUSHs      25: RET

+-------------------+
| Variablen (160 B) | > Nicht mehr auf dem Stack
+-------------------+ <- RSP (9904), RBP (9904)
| alter RBP: 10000  |
+-------------------+
| Rückspr.-Addr: 11 |
+-------------------+
| Variablen (80 B)  |
+-------------------+
| Rücksprungadresse |
+-------------------+

Stack 7

 f:
   20: PUSH RBP             23: MOV RSP, RBP
   21: MOV RBP, RSP      => 24: POP RBP
   22: Beliebige PUSHs      25: RET

+-------------------+
| Variablen (160 B) | \
+-------------------+   > Nicht mehr auf dem Stack
| alter RBP: 10000  | /
+-------------------+ <- RSP (9904)
| Rückspr.-Addr: 11 |
+-------------------+
| Variablen (80 B)  |
+-------------------+ <- RBP (1000)
| Rücksprungadresse |
+-------------------+

Stack 8

 f:
   20: PUSH RBP             23: MOV RSP, RBP
   21: MOV RBP, RSP         24: POP RBP
   22: Beliebige PUSHs   => 25: RET

+-------------------+
| Variablen (160 B) | \
+-------------------+  |
| alter RBP: 10000  |   > Nicht mehr auf dem Stack
+-------------------+  |
| Rückspr.-Addr: 11 | /
+-------------------+ <- RSP (9904)
| Variablen (80 B)  |
+-------------------+ <- RBP (1000)
| Rücksprungadresse |
+-------------------+

Zu Übung 9, Aufgabe 2 b)

Allgemeines

Wenn wir ein Assembler-Programm schreiben, mit einer main-Funktion, kann ich die nach dem assemblieren enstehende o-Datei mit dem gcc kompilieren und bekomme ein lauffähiges Programm.

global main
section .text
main:
    mov rax, 0
    ret
nasm -f elf64 test.asm # Erzeugt test.o
gcc -o test test.o     # Erzeugt test
./test                 # Führt es aus

1. Länge des Testarrays aus den Konsolenparametern auslesen

Die Signatur der main-Funktion ist

int main(int argc, char *argv[])

Man bekommt also im ersten Parameter (rdi) die Anzahl der Parameter und im zweiten (rsi) ein Array von Adressen, an denen die Parameter im Speicher stehen. Der 0. Parameter ist immer der Name des Programms, es gibt also immer einen Parameter mehr, als man übergibt.

Die Adressen(!) der einzelnen Parameter-Strings(!) erhält man entsprechend per [rsi], [rsi+8], [rsi+16], etc.

2. String to Int

Externe Bibliotheksfunktionen kann man aufrufen, wenn man dem Assembler sagt, dass die Funktion extern zur Verfügung gestellt wird. Um einen String zu einer Zahl umzuwandeln gibt es beispielsweise die Funktion strtoul, deren Signatur wie folgt aussieht:

unsigned long int strtoul(const char *nptr, char **endptr, int base);

Wir müssen ihr also drei Parameter übergeben (wie bei der von euch implementierten strToInt-Funktion). Hier hatte sich im ersten Tutorium der Fehler versteckt, da ich nur einen Parameter übergeben hatte. Der zweite Parameter kann einfach auf 0 gesetzt werden.

global main
extern strtoul
section .text
main:
    ; Hier die Parameter korrekt belegen
    call strtoul
    ; Jetzt steht das Ergebnis von strtoul in rax
    ret

4. Arrayeinträge mittels der C-Bibliotheksfunktion rand mit Zufallswerten befüllen

Hier verwenden wir wie oben eine Bibliotheksfunktion, nämlich rand. Wenn rand nicht initialisiert wird (siehe dazu srand), gibt es bei jedem Programmaufruf immer die gleiche Folge von Werten zurück.

5. / 7. Ausgabe des Arrays

Um Text und/oder Zahlen auszugeben, gibt es die Funktion printf (deutsche Wikipedia). Der erste Parameter ist eine Adresse auf einen String. Sind in dem String Platzhalter enthalten (etwas, das mit % beginnt), so werden weitere Parameter erwartet. Diese werden ganz normal entsprechend der Calling Convention übergeben. Für euch wichtig ist eigentlich hauptsächlich der Platzhalter %lu für eine 64bit-Zahl ohne Vorzeichen.

Wichtig: Damit euer Programm nicht abstürzt, müsst ihr vor Aufruf von printf das Register rax auf 0 setzen. In rax erwartet printf die Anzahl der verwendeten xmm-Register. Da wir nicht mit Kommazahlen arbeiten, muss da eine 0 drin stehen.

Texte können/müssen im Assembler-Programm im .data-Bereich abgelegt werden.

global main
extern printf
section .data
    ; db = Speichere eine Folge von Bytes
    ; 10 = Zeilenumbruch
    ; NIE die 0 am Ende vergessen!
  text:
    db "Hallo!", 10, 0
  mit_param:
    db "Die Zahl ist %lu.", 10, 0
section .text
main:
    ; printf ohne zusätzlichen Parameter
    mov rdi, text
    call printf
    ; printf mit zusätzlichem Parameter
    mov rdi, mit_param
    mov rsi, 5345
    call printf
    ret

Abschluss

Das sollte eigentlich alle offenen Fragen soweit klären, dass ihr an der Aufgabe arbeiten könnt.