Rechnerarchitektur

Werbung
Prof. Dr. K. Wüst
FH Gießen–Friedberg, FB MNI
WS 2006/2007
Studiengang Informatik
Rechnerarchitektur
2. Hausübung mit Lösungen
Unterprogramm für eine CPU08
Für einen Spannungsteiler mit zwei Widerständen R1 und R2 gilt:
Uges =
R1 + R2
U2
R2
Schreiben Sie für einen Mikrocontroller der 68HC08-Reihe mit CPU08-Prozessor ein Unterprogramm, das diese Berechnung durchführt. Die Schnittstelle des Unterprogramms
soll wie folgt aussehen:
Bei Aufruf: U2 wird in Register A übergeben
Bei Rückkehr: Das Ergebnis Uges wird in Register A zurückgegeben
R1 und R2 sind 8-Bit-Variablen, die im Datenbereich angelegt und mit den richtigen
Werten belegt sind; sie sollen bei Ausführung des Unterprogrammes benutzt werden. Es
soll durchgehend mit positiven (vorzeichenlosen) Zahlen gerechnet werden. Dabei werden
unvermeidliche Rundungsfehler auftreten.
Aufgaben
1) Implementieren Sie ein entsprechendes Unterprogramm für die CPU08. Nutzen Sie
dabei die arithmetischen Befehle der CPU möglichst gut aus.
Vorüberlegungen
Zur Berechnung des angegebenen arithmetischen Ausdrucks sind drei arithmetische Operationen notwendig, mit denen schrittweise das Ergebnis aufgebaut wird. Beim Programmentwurf sollte man Vorüberlegungen anstellen:
a) Die Addition; sie könnte zu einem Übertrag (Carry) führen, wenn die Zahlen zu groß
sind. Für die momentan angegebenen Zahlenwerte ist die Addition unkritisch, 8 Bit reichen aus. Für den Fall späterer Programmänderungen (R1 , R2 ) könnte man das Carryflag
überprüfen.
b) Ablauf auf der CPU08: Multiplikator in A, Multiplikand in X, Ergebnis in X-A. Maximalwerte: X=255, A=255, X-A=65025. Die Multiplikation ist unkritisch, da das Registerpaar X-A immer ausreicht um das Produkt zweier 8-Bit-Zahlen aufzunehmen.
c) Ablauf: Dividend in H-A, Divisor in X, Ergebnis in A, Rest in H. Maximalwerte: HA=65535, X=255, A=255, H=254. Die Division ist kritisch; sie darf nicht auf zu große
2.Hausübung Rechnerarchitektur - Prof. Dr. K. Wüst
2
Ergebnisse führen da für das Ergebnis nur ein 8-Bit-Register (A) zur Verfügung steht.
Wenn das Divisionsergebnis in A zu klein ist, gibt es ebenfalls ein Problem: Es bleibt ja
ein Rest, der nicht mehr geteilt werden konnte. Der Rest kann maximal Divisor-1 sein.
Für ein korrektes Ergebnis müsste dieser Rest noch durch den Divisor geteilt werden. Die
Wertigkeit eines vernachlässigten Restes kann sich daher der 1 annähern, was bei kleinem
Divisionsergebnis prozentual ein sehr großer Fehler ist.
Daran muss sich die Reihenfolge der Operationen ausrichten. Beispiel:
x
x
x
x
=
=
=
=
R1 ; x=30
x + R2 ; x=180
x/R2 ; x=1 (!?)
x*U2 ; ...
Da R1=30 und R2=150 wird im dritten Schritt 180/150 gerechnet, das Ergebnis ist zu
klein, nämlich 1, und enthält einen Fehler von ca. 17%, der sich nur mit aufwändiger
Auswertung des Divisionsrestes wieder gutmachen lässt. Eine bessere Reihenfolge ist:
x
x
x
x
=
=
=
=
R1
x + R2
x*U2
x/R2
Hier entstehen Zahlen, die vom Prozessor mit ausreichender Genauigkeit verarbeitet werden können. Beispiel:
Für R1=30, R2=150 und U2=199 ergibt sich ein Ergebnis von 238
x
x
x
x
=
=
=
=
R1 ; x=30
x + R2 ; x=180
x*U2 ; x=35820
x/R2 ; x=238, Rest 120
Der Rest kann maximal (Teiler-1) sein, also hier 149. Das entspricht einem Nachkommaanteil von fast 1. Dann hat man einen relativen Fehler von ca. 1/240, also 0.4 %. Das
ist nur ein kleiner Fehler, die Berechnungsreihenfolge ist also für größere Werte von U2
akzeptabel. Bei kleinen Werten für U2 wird aber das Divisionsergebnis wiederum sehr
klein und der relative Fehler steigt an. Bei U2=1 ergibt sich
x
x
x
x
=
=
=
=
R1 ; x=30
x+R2 ; x=180
x*U2 ; x=180
x/R2 ; x=1
Da das mathematisch korrekte Ergebnis 1.2 ist, liegen auch hier wieder ca. 17% Fehler vor.
Damit ist Frage 3 schon in der Entwurfsphase beantwortet. Für kleine Spannungswerte
U2 ist der Berechnungsgang also sehr ungenau, je nach Applikation aber tolerierbar.
Eine Implementierung in CPU08-Assembler muss für Addition, Multiplikation und Division immer die Zwischenergebnisse in die richtigen Register bereit legen. Dies kann z. B.
über den Stack erfolgen.
2.Hausübung Rechnerarchitektur - Prof. Dr. K. Wüst
3
Beispiel-Lösung
;
;
;
;
;
;
;
;
;
;
;
;
;
*************************************************************
Unterprogramm Uges
Uges = (R1+R2)/R2
* U2
Eingabe:
Parameter: U2 in A, maximal 212
R1 und R2 auf Speicherplätzen mit genau diesem Variablennamen
Ausgabe:
Bei Rückkehr aus dem Unterprogramm Ergebnis in A
*************************************************************
Uges:
psha
;
lda R1
;
add R2
;
bcs Fehler
pulx
;
mul
;
pshx
;
pulh
;
ldx R2
;
div
;
;
bcs Fehler
rts
Fehler:
retten auf Stack
R1 in Akku laden
Akku enthält R1+R2
; Carryflag zeigt Überlauf bei Addition an
Um von Stack holen in Register X
X-A enthält U2*(R1+R2)
X nach
... H bringen
X=R2
A = U2*(R1+R2)/R2
Ergebnis liegt in A, Rest in H
; Carryflag zeigt Überlauf bei der Division an
; Fehlerbehandlung hier ergänzen
rts
2) Geben Sie an, mit wie vielen Byte der Stack bei Ausführung des Programmes maximal
belegt ist.
Lösung Bei Aufruf des Unterprogrammes wird die Rücksprungadresse auf den Stack
gelegt (2 Byte). Da im Unterprogramm nach jedem PUSH-Befehl auch wieder ein PULBefehl folgt, beträgt die maximale Stackbelegung 3 Byte.
3) Geben Sie an, für welchen Wertebereich von U2 ein (im Rahmen der Rundungsfehler)
richtiges Ergebnis berechnet wird, wenn R1=30 und R2=150 ist.
Lösung Das Ergebnis wird gemäß Aufgabenstellung im Register A zurückgegeben kann
also maximal den Wert 255 haben. Im Maximalfall gilt also:
Uges =
R1 + R2
U2 = 255
R2
2.Hausübung Rechnerarchitektur - Prof. Dr. K. Wüst
4
Aufgelöst nach U2 ergibt sich
U2 = 255
R2
150
= 255
= 212.5
R1 + R2
180
Der maximale Eingabewert für U2 der noch korrekt verarbeitet wird ist 212. Man kann das
ausprobieren, im oben angegebenen Programm entsteht bei größeren Werten ein Überlauf
(CF=1) beim Divisionsbefehl.
4) Geben Sie an, welchen prozentualen Rundungsfehler das Ergebnis enthält, wenn R1=30,
R2=150 und U2=1 ist.
Lösung Gemäß Vorüberlegungen 20 %. (siehe oben)
Tipps
• Laden Sie sich das Handbuch der CPU08 herunter aus dem e-study-Portal im Kurs
Rechnerarchitektur unter Literatur“.
”
• Beachten Sie, dass bei der Multiplikation und Division mehrere Register beteiligt
sind. Lesen Sie dazu die Beschreibung der Befehle MUL und DIV im Handbuch.
• Laden Sie sich die CodeWarrior-Entwicklungsumgebung (CodeWarrior Development
Studio for HC08 Microcontrollers, Windows-Version) vom Hersteller Freescale von
der URL
http://www.freescale.com/webapp/sps/site/overview.jsp?nodeId=01272600612247
herunter und testen Sie Ihren Entwurf mit dem Simulator aus! Der Link ist im
Kurs Rechnerarchitektur des e-study-Portals vorhanden, Sie müssen sich aber vor
dem Downlaod registrieren. Um ein Assemblerprogramm einzugeben und zu starten
machen einfach Sie folgendes:
1. File / New...
2. HC(S)08 New Project Wizard
3. Project name: Hier einen Projektnamen eingeben
4. Please choose the set of languages to be supported: Assembly
5. select the derivative you would like to use: HC08 / G-Family / 68HC908GP32
und connection: Full chip simulation
6. Add existing files to the project: keine (gleich weiter)
7. Rapid Application Development Options: None
8. Fertig stellen
9. Doppelklick auf File main.asm“
”
10. Zum Debuggen klicken Sie einfach auf das Symbol mit dem Käfer. Dort finden
Sie im Menü Run“ weitere Befehle, wie Start, Single Step und Restart.
”
Herunterladen