FAKULTÄT FÜR INFORMATIK TECHNISCHE UNIVERSITÄT MÜNCHEN Lehrstuhl für Rechnertechnik und Rechnerorganisation Prof. Dr. Arndt Bode Einführung in die Rechnerarchitektur Wintersemester 2016/2017 Zentralübung 1 28.10.2016 Maschinennahe Programmierung (1) Ganzzahlige Arithmetik mit dem 80386 Grundlagen zum Programmiermodell des 80386 Um Daten (z.B. Zahlenwerte) zu verarbeiten, werden diese bei fast allen Prozessoren in sogenannten Registern gespeichert. Der Intel 80386 hat dazu vier Allzweck-Datenregister mit den Namen EAX, EBX, ECX, EDX von je 32 Bit Breite, in denen Operanden und Ergebnisse arithmetischer und anderer Operationen gespeichert werden können. Damit können also je nach Interpretation der Register Werte zwischen -231 und 231 − 1 oder zwischen 0 und 232 − 1 dargestellt werden. Eine Besonderheit der Intel 80386 Prozessoren ist, daß sich jedes der vier Register aus der Data-Gruppe (EAX, EBX, ECX und EDX) auch noch in 16Bit und als Registerpaar“ aus ” zwei 8-Bit Registern ansprechen lässt (siehe Abb. 1). Das 32-Bit Wort, das in einem Data-Register (z. B. EAX) gespeichert ist, ist mit seinen unteren 16Bit in AX zugreifbar. AX ist wiederum in das niederwertige Byte (low byte) und das höherwertige Byte (high byte) geteilt. Über die zusätzlichen Registernamen AL (AX Low) und AH (AX High) lassen sich dann das Low-Byte bzw. das High-Byte des EAX/AX Registers ansprechen. Hieraus folgt natürlich, daß EAX, AX, AL und AH nicht unabhängig voneinander benutzbare Register sind! Zum Beispiel sich der Wert von AX als 256 × AH + AL. Analoges gilt für das EBX, das ECX und das EDX Register. Weitere Register Es gibt mit ESI, EDI und EBP noch drei weitere fast-Allzweck“ Register, diese sind aber ” ausschließlich mit 16 oder 32Bit nutzbar; es gibt aus historischen Gründen keine 8Bit-Teile. Einen Gesamtüberblick aller 80386-Register gibt es in der nächsten Übung. 1 31 15 8 7 0 EAX AH AL AX EAX BH BX BL EBX CH CX CL ECX DH DX DL EDX SI ESI DI EDI BP EBP Abbildung 1: Registernamen der wichtigsten 80386-Register Assembler Die Befehle eines Prozessors sind zunächst verschiedene Zahlenkombinationen, sog. Opcodes“ ” (=Operation Codes, beim 80386 typ. 1-16 Bytes lang), die die auszuführende Aktion beschreiben und vom Prozessor direkt verarbeitet werden können. Da diese Zahlen nicht besonders eingängig sind, gibt es für den Programmierer eine Vereinfachung, sogenannte Mnemonics“. Dies sind einfach zu merkende, textuelle Befehle, ” die mit Übersetzungstabellen in die benötigten Zahlenwerte umgesetzt werden können. Die Übersetzung kann auch mit einem speziellen Programm erfolgen, dieses wird dann Assembler“ ” genannt. Die Rückübersetzung in Mnemonics zur Fehlersuche etc. wird als Disassemblierung“ ” bezeichnet. Hinweis: Bei den Befehlen ist die Groß/Kleinschreibung nicht wichtig. Die Befehle werden im folgenden meist groß geschrieben, um sie stärker hervorzuheben. Grundrechenarten mit dem 80386 Es stehen alle 4 Grundrechenarten und die Bildung des Zweierkomplements zur Verfügung: 2 Befehl ADD Ziel, Quelle SUB Ziel, Quelle NEG Ziel MUL Quelle DIV Quelle Erläuterung Ziel := Ziel + Quelle Ziel := Ziel − Quelle Ziel := −Ziel (Bildung des Zweierkomplements) EDX:EAX := EAX*Quelle (vorzeichenlose Multiplikation mit 64Bit-Ergebnis, die niederwertigen 32Bit sind in EAX) EAX := (EDX:EAX)/Quelle, EDX:=Rest von EAX/Quelle vorzeichenlose 64Bit-Division mit ganzahligem Ergebnis in EAX und Rest in EDX Als Ziel dürfen (zunächst) nur Register angegeben werden (Erweiterung in Übung 2). Quelle kann ein Register oder auch ein direkter Zahlwert (Konstante, sogenannte Immediate“) sein. ” Die Verarbeitungsbreite (32, 16, 8Bit) wird von den Operandregistern definiert. MUL und DIV erlauben nur ein Register als Quelle, das Ziel ist immer EAX/AX bzw. EDX/DX! Die Division erwartet bei einem 16Bit-Register als Divisor einen 32Bit-Wert als Ausgangswert, für einen 32-Bit-Divisor einen 64Bit-Wert. Dieser setzt sich aus DX bzw. EDX für die höherwertigen 16 bzw. 32Bit und AX/EAX für die niederwertigen 16/32 Bit zusammen (Notation DX:AX bzw. EDX:EAX). Eine Division durch 0 führt erst bei der Ausführung zu einem Fehler (sog. Ausnahme). Diese bricht das Programm normalerweise ab. Für ADD Ziel,1 bzw. SUB Ziel,1 gibt es aus historischen Gründen noch die Befehle INC Ziel bzw. DEC Ziel. Diese erhöhen (inkrementieren) bzw. erniedrigen (dekrementieren) das Ziel um 1. Da diese Befehle ausser dem Register keine Operanden brauchen, sind sie kürzer und waren daher früher schneller in der Ausführung. Beispiele: ADD EAX,EBX ADD AX,BX SUB EBX,10 NEG ECX MUL ECX DIV EBX INC BL DEC ESI aber: ADD AX,BL ADD AX,EBX MUL 10 MOV SL,0 EAX := EAX+EBX (32Bit Addition) AX := AX+BX (16Bit Addition) EBX := EBX-10 ECX := -ECX EDX:EAX := EAX*ECX EAX := (EDX:EAX)/EBX, EDX := Rest (EAX/EBX) BL := BL+1 (8Bit) ESI := ESI-1 FALSCH! FALSCH! FALSCH! FALSCH! 8 und 16 Bit können nicht direkt addiert werden! 16 und 32 Bit können nicht direkt addiert werden! MUL kann nur Quellregister, keine Konstanten! SI hat keinen ansprechbaren 8Bit-Teil! Hinweis: Für vorzeichenbehaftete Multiplikation und Division gibt es spezielle Befehle, die etwas flexibler in den Parametern sind. Diese werden später behandelt. Transportbefehl MOV Um Daten ohne Veränderung zwischen den Registern zu bewegen, existiert der MOV-Befehl ( Move“). Dieser setzt bzw. kopiert je nach angegebenem Register (8, 16 oder 32Bit) einen ” Wert in dieses. Kopieren heißt in diesem Zusammenhang, dass das zu kopierende Register (d.h. die Quelle) nicht verändert wird! Die Bezeichnung Move (verschieben) ist also nicht ganz korrekt. 3 Befehl Erläuterung MOV Ziel, Quelle Ziel = Quelle Ziel kann (vorerst) nur ein Register sein, die Quelle kann zunächst nur ein Register oder auch eine Konstante sein. Mit einer Konstante kann z.B. der für MUL nötige Register-Multiplikator geladen werden. Beispiele: MOV AX, 10H MOV EAX, 10H MOV EBX, EAX MOV AL,BH aber: MOV BL,AX MOV EAX,BL MOV BL,300 Lade die 16Bit-Konstante 1016 nach AX Lade die 32Bit-Konstante 1016 nach EAX Kopiert den Inhalt von EAX nach EBX, EAX wird nicht verändert Kopiert die oberen acht Bit von BX in die unteren 8 Bit von AX (die oberen 24Bit von EAX werden nicht verändert) FALSCH! 16Bit können nicht in 8Bit kopiert werden! FALSCH! 8Bit können so nicht in 32Bit kopiert werden! FALSCH! 300 passt nicht mehr in 8Bit! Angabe symbolischer Konstanten In manchen Fällen ist es aus Entwicklungsgründen ungünstig, direkt die Zahlkonstanten in die Befehle zu schreiben. Um dies zu umgehen, ist es in allen Assemblern möglich, symbolische Namen als Platzhalter anzugeben, die bei der Assemblierung durch einen anderswo definierten Wert ersetzt werden (Textersetzung). Diese Definitionen erfolgen üblicherweise mit einem Pseudo-Befehl“ 1 , z.B. equ (equals). Die Symbole selbst (also Name mit Doppelpunkt) werden ” auch als Marken bzw. Labels bezeichnet, sie können auch ohne Pseudobefehle benutzt werden, um eine bestimmte Position zu markieren (dazu später mehr). Beispiel: startwert: EQU 15 .... MOV EAX,startwert ; Lädt EAX mit ’startwert’, also 15 MOV EBX,startwert+1 ; Lädt EBX mit ’startwert+1’, also 16 1 Pseudo“ deshalb, weil es kein echter Prozessorbefehl ist, sondern eine Anweisung, die nur der Assembler ” versteht. 4 Aufgaben Aufgabe 1.1 Die ETI-Waschmaschine informiert den Benutzer nach dem Start über die geschätzte Gesamtdauer eines Waschprogramms. Diese berechnet sich aus 3 vom Waschprogramm abhängigen Zeiten (Vorwäsche VW, Hauptwäsche HW, Schleudern SCH) und einem festen Wert, der das abschliessende Sicherheitsabpumpen und Auflockern der Wäsche (Trommel kurz hin- und her bewegen) beinhaltet. ☞ Schreiben Sie ein x86-Assembler-Programm, dass die Gesamtwaschzeit errechnet. Der feste Wert betrage 50 Sekunden, die Sekundenzeiten für VW, HW und SCH sind bereits in den 16-Bit Registern AX, BX und CX abgelegt, das Rechenergebnis soll in DX stehen. Mehr als 4 Befehle sollten Sie nicht dazu benötigen. Aufgabe 1.2 Unsere Waschmaschine zeigt dem Benutzer immer die aktuelle Temperatur des Waschwassers an. Dazu werden die Daten eines Temperatursensors ausgewertet, der vorzeichenlose Werte zwischen 0 und 255 liefert. Allerdings müssen diese Werte umgerechnet werden, da der Sensorwert 0 einer Temperatur von 100◦ C und Sensorwert 255 einer Temperatur von 10◦ C entspricht. Ansonsten arbeitet der Sensor innerhalb dieses Bereichs linear. ☞ Wie muss man allgemein die aktuelle Temperatur aus dem gelieferten Sensorwert berechnen? ☞ Welche Probleme ergeben sich mit der Umrechnungsformel, wenn man nur mit ganzen Zahlen rechnen kann? Wie kann man diese umgehen? ☞ Wie müsste ein Programmstück in x86-Assembler aussehen, das diese Temperaturberechnung möglichst fehlerfrei durchführt? Der Sensorwert liege vor Beginn der Rechnung im 8-Bit Register BL, das Rechenergebnis soll im 32-Bit Register EAX stehen. ☞ Welche Möglichkeiten gibt es noch zur Umrechnung? Welche Vor- bzw. Nachteile haben sie? Falls Sie noch Fragen haben, wenden Sie sich bitte an Ihre Tutoren oder Marcel Meyer, E-Mail: [email protected] 5
© Copyright 2025 ExpyDoc