TI2/Rechnerarchitektur-Tutorium, 01.12.2016

Nachbesprechung

Aufgabe 1: 23 + 81

1er/2er/B+V:            
  23     0001 0111      
+ 81   + 0101 0001      
==================      
 104     0110 1000        
Offset:
23 + 128 = 151 = 1001 0111
81 + 128 = 209 = 1101 0001
        carry: 1   1  111         
==========================
               1 0110 1000
             -   1000 0000 (Doppeltes Offset abziehen)
             =============
                 1110 1000 = 104 + 128

Aufgabe 1: 36 - 14

B+V:
  36      0010 0100
- 14    - 0000 1110
            11 11
===================
  22      0001 0110
1er:
 36      0010 0100
-14    + 1111 0001
carry: 1 11         
       ===========
       1 0001 0101 Übertrag hinten aufaddieren =>
       + 0000 0001 => "end-around-carry"
       ===========
         0001 0110

Aufgabe 1: 36 - 14 (contd.)

2er:
 36      0010 0100
-14    + 1111 0010
carry: 1 11         
       ===========
       1 0001 0110 Übertrag kann ignoriert werden, wenn
                   linkesten beiden carry-bits gleich sind

Aufgabe 1: 36 - 14 (contd.)

Offset:
 36 + 128 = 164 = 1010 0100
-14 + 128 = 114 = 0111 0010

ähnlich B+V am besten (36) - (14) rechnen und nicht (36) + (-14)
         1010 0100
       + 0111 0010
carry: 1 11
       ===========
       1 0001 0110
     -   1000 0000
      ============
         1001 0110 = 128 + 22

Aufgabe 1: 72 - 87

B+V:
 72 = 0 100 1000
-87 = 1 101 0111

Berechnung: - (87 - 72)
  0101 0111
- 0100 1000
     1       (carry)
===========
  0000 1111 = 15

Aufgabe 1: 72 - 87 (contd.)

1er:
 72      0100 1000
-87    + 1010 1000
carry:      1
       ===========
         1111 0000 = -15
2er:
 72      0100 1000
-87    + 1010 1001
carry:      1
       ===========
         1111 0001 = -15

Aufgabe 1: 72 - 87 (contd.)

Offset:
 72 = 1100 1000
-87 = 0010 1001

Berechnung: 72 + (-87)
         1100 1000
       + 0010 1001
carry:      1
       ===========
         1111 0001
       - 1000 0000
       ===========
         0111 0001 = 128 - 15

Hinweise zum Übungszettel

Funktionssignatur

int64_t strToInt(const char*, char**, uint8_t)
  • In rdi steht die Adresse, an der der String/Text anfängt
  • In rsi findet ihr eine Adresse, an die ihr eine Adresse schreiben sollt (zunächst nicht so wichtig)
  • In dl (niedrigstes Byte von rdx) steht die Basis

Strings

  • Ein String ist (in der Regel) als eine Abfolge von Bytes gespeichert
  • Als letztes Byte steht immer das Byte mit der Zahl/dem Wert 0
  • Jedes Byte (bis auf das letzte) steht für einen Buchstaben
  • Die Zuordnung der Zahl (0-255) zu einem konkreten Zeichen passiert über den ASCII-Code

  • Beispiel: Hallo entspricht den 6 Zahlen 72, 97, 108, 108, 111, 0

Speicherzugriffe

Grundlegender Zugriff auf Speicherbereiche

  • Können über eckige Klammern auf einen Speicherbereich zugreifen

  • Zahl / Wert in Klammern gibt immer die Startadresse an

; Kopiert Speicherstellen 345 bis 352 (8 Byte) in rax
; 8 Byte, da RAX 64-Bit-Register ist
mov rax, [345]
; Kopiert Speicherstellen 345 bis 348 (4 Byte) in eax
; 4 Byte, da EAX 32-Bit-Register ist
mov eax, [345]
; Kopiert rbx in Speicherstellen rax bis rax+7 (8 Byte)
; 8 Byte, da RBX 64-Bit-Register ist
mov [rax], rbx

Erweiterter Zugriff auf Speicherbereiche

  • Die Größe des zu kopierenden Speichers kann auch explizit angegeben werden

  • Teilweise muss man das auch explizit tun, z.B. bei Konstanten

    mov [rbx], 12 ; Unklar wie viel Bit die Zahl haben soll
    mov [rbx], BYTE 12 ; Kopiert 8 Bit
    mov [rbx], WORD 12 ; Kopiert 16 Bit
    mov [rbx], DWORD 12 ; Kopiert 32 Bit
    mov [rbx], QWORD 12 ; Kopiert 64 Bit
  • Interessant sind hier auch die Befehle MOVZX/MOVSX

    • Kopieren z.B. ein 8-Byte-Wert aus dem Speicher in ein 64-Bit-Register
    • Entweder mit Sign-Extension (MOVSX) oder Zero-Extension (MOVZX)

Berechnung von Speicheradressen

  • Nicht nur einfache Register oder feste Zahlen sind möglich

  • Allgemein: address = scale * index + base + offset

    • scale {1,2,4,8}

    • index {rax, rbx, rcx, rdx, rbp, rsi, rdi}

    • base {rax, rbx, rcx, rdx, rbp, rsp, rsi, rdi}

    • offset kann sowohl Register als auch eine Zahl sein

    mov rax, [rbx + 4*rdi + 7]
  • Sinnvoll z.B. für Arrayzugriffe in Schleifen

    • base ist der Array-Beginn
    • index ist der Array-Index (beginnt bei 0)
    • scale ist die Größe der Array-Einträge