TI2/Rechnerarchitektur-Tutorium, 03.11.2016

Organisatorisches

Fragen vorab

  • NASM und benötigte Werkzeuge erfolgreich installiert?
  • Konfiguration getestet?
  • Wie sieht es mit dem 1. Übungszettel aus?

Vorlesung

von-Neumann-Architektur

  • Programme = Daten
Aufbau der Von-Neumann Architektur, 2007, Lukas Grossar, Public Domain
Aufbau der Von-Neumann Architektur, 2007, Lukas Grossar, Public Domain

Simpler Interpreter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Interpreter {
static int PC;              // Program counter holds the address of the next instruction
static int AC;              // Register for doing arithmetic, accumulator
static int instruction;     // Current instruction
static int instructionType; // Type of the current instruction, i.e. what to do
static int dataLocation;    // Address of the data for the instruction
static int data;            // Holds the operand
static boolean runBit=true; // Bit used to halt the computer

public static void interpreter (int memory[], int startingAddress) {
   PC = startingAddress;                                      // Initialize the program
   while( runBit ) {
       instruction = memory[PC];                              // Fetch next instruction
       PC = PC + 1;                                           // Increment PC
       instructionType = getInstructionType(instruction);     // Determine instruction
       dataLocation = findData(instruction, instructionType); // Locate data
       if( dataLocation >= 0 )                                // No operand if -1
           data = memory[dataLocation];                       // Fetch data
       execute(instructionType, data);                        // Execute instruction
   }
}
}

(Beispiel aus der Vorlesungsfolie.)

Assembler

Register vs. Hauptspeicher

  • Hauptspeicher ist zu langsam für die CPU
  • CPU hat zusätzlichen schnellen Speicher direkt an der CPU: Register
    • rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, r8, r9, r10, r11, r12, r13, r14, r15
    • (Nur) auf den Registern können Operationen ausgeführt werden
  • Die ersten 8 Register haben spezielle Bedeutung
    • Vor allem bei Funktionsaufrufen (Calling Conventions)

Register

  • Wir haben 16 Register

    • schnelles Rechnen

    • Übergabe von Parametern

    • Rückgabe von Funktionswerten

Register im Detail

Siehe hierzu die AMD-Doku, Seite 39, PDF-Seite 75.

Assembler-Operationen

  • Aufbau: operation operand_1, operand_2

  • Manchmal nur ein Operand, manchmal auch keiner, sehr selten auch drei

  • operand_x kann je nach operation verschiedenes sein:

    • Register (rax, rbx, …)
    • Konstanter Wert (234, 45, …)
    • Sprungmarke (im Data-Bereich)
    • Speicherstelle ([rax+8]; kommen wir in einem späteren Tutorium noch zu)

Kopiere Wert

Syntax

mov zieloperand, quelloperand

Semantik

zieloperand = quelloperand

Beispiel

1
2
mov rdi, 42  ; rdi = 42
mov rbx, rdi ; rbx = rdi

Inkrement

Syntax

inc zieloperand

Semantik

zieloperand = zieloperand + 1

Beispiel

1
2
3
; rax = 45 + 1
mov rax, 45
inc rax

Dekrement

Syntax

dec zieloperand

Semantik

zieloperand = zieloperand - 1

Beispiel

1
2
3
; rax = 45 - 1
mov rax, 45
dec rax

Addition

Syntax

add zieloperand, quelloperand

Semantik

zieloperand = zieloperand + quelloperand

Beispiel

1
2
3
; rdx = 45 + 32
mov rdx, 45
add rdx, 32

Subtraktion

Syntax

sub zieloperand, quelloperand

Semantik

zieloperand = zieloperand - quelloperand

Beispiel

1
2
3
; rcx = 45 - 32
mov rcx, 45
sub rcx, 32

Programmsteuerung

Bisher

  • Langweilige Programme

    • Keinerlei Bedingungen, Schleifen, etc.
  • Schön wäre so etwas wie

    if <Bedingung> then
        <Code>
    else
        <Code>

    oder

    while <Bedingung>
        <Code>
    end
  • Geht leider nicht so einfach

Sprung

  • Wir können innerhalb unseres Programms springen:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    func:
        jmp marke2
    marke1:
        mov rax, rbx
        jmp marke3
    marke2:
        mov rbx, 20
        jmp marke1
    marke3:
        ret
  • jmp marke bedeutet: Setze das Programm in der Zeile mit marke: fort.

  • Leider wird immer gesprungen.

Vergleichen

  • Wir wollen nur bei bestimmten Bedingungen springen.

  • Bedingung bedeutet meistens: Wir wollen zwei Werte miteinander vergleichen.

Syntax

cmp operand_1, operand_2

Semantik

Rechne operand_1 - operand_2 und setze Statusregister.

Statusregister

  • Zusätzlich zu den Registern, mit denen wir rechnen hat die CPU noch sogenannte Statusregister.
  • Speichern zusätzliche Informationen zum Ergebnis
    • z.B.: ZF wird auf 1 gesetzt, wenn das Ergebnis einer Operation 0 ist

Bedingter Sprung

  • Es gibt Sprungbefehle, die nur springen, wenn bestimmte Bedingungen wahr sind bedingte Sprünge

  • Sie arbeiten auf Basis der Statusregister

  • Meist in Kombination mit einem davor ausgeführten CMP-Befehl

Beispiele

  • je marke springt zu marke wenn die verglichenen Operanden gleich sind (jump if equal).

  • jne marke springt zu marke wenn die verglichenen Operanden nicht gleich sind (jump if not equal).

  • Weitere sind zu finden im Handbuch (AMD: Seite 215; Intel: Seite 166)

Bedingter Sprung (weiter)

Produkt berechnen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
produkt: ; Am Ende soll rax = rdi*rsi sein
    mov rax, 0

loop:
    cmp rsi, 0 ; if rsi == 0 then goto end
    je end

    dec rsi
    add rax, rdi

    jmp loop

end:
    ret