• Keine Ergebnisse gefunden

Eine typische Anwendung ist das tempor¨are Zwischenspeichern von Daten. Beachten Sie im folgenden Beispiel die Reihenfolge der PUSH und POP-Befehle:

push dx ;dx zwischenspeichern push ax ;ax zwischenspeichern

mov dx, offset Meldung ;dx wird gebraucht mov ah,09

9.4. TESTFRAGEN 79 int 21h

pop ax ;ax erh¨alt wieder den alten Wert pop dx ;dx erh¨alt wieder den alten Wert

Manchmal kann auch ein Transport von Daten gut ¨uber den Stack abgewickelt werden. Im folgenden Beispiel soll der Inhalt von DS nach ES kopiert werden. Dies kann geschehen durch

mov ax,ds ; DS kann nicht direkt nach ES kopiert werden mov es,ax ; AX ist ver¨andert

Das gleiche kann auch ¨uber den Stack als Zwischenstation geschehen:

push ds ; Keine anderen Register werden ver¨andert pop es

Die Benutzung des Stack erlaubt z.B. auch beliebig tief geschachtelte Schleifen, die alle mit dem Register CX z¨ahlen.

9.4 Testfragen

1. push di push dl push fs push edi

Welche Befehle sind fehlerhaft?

2. push 8 push 9 push 10 pop ax pop bx pop cx

Welchen Inhalt haben die Register ax,bx,cx?

3. mov cx,10 mult: imul ax,2

push ax dec cx cmp cx,0 jne mult mov di,0

vom_stack_holen: pop ax mov [Feld+di],ax

80 KAPITEL 9. STACK UND STACKBEFEHLE add di,2

cmp di,20

jbe vom_stack_holen

Kommentieren Sie diesen Programmabschnitt!

L¨osungen auf Seite 130

Kapitel 10

Unterprogramme

Unterprogramme, engl. Procedures oder Subroutines, sind notwendig, um gute Assemblerpro-gramme zu schreiben. Die Gr¨unde daf¨ur sind:

• Die Ablaufsteuerung f¨ur Teilaufgaben ist zentral und nur einmal vorhanden

• Gute Unterprogramme sind modular und unterst¨utzen die Wiederverwendung

• Eine unn¨otige Aufbl¨ahung des Maschinencodes wird vermieden

• Die ¨Ubersicht wird verbessert

• Unterprogramme stellen gute Schnittstellen zu Hochsprachen dar

Mit dem Aufruf des Unterprogramms (CALL) verzweigt der Programmablauf ins Unterpro-gramm. Das Unterprogramm endet mit dem Return-Befehl (RET). Dieser bewirkt, dass die Ausf¨uhrung mit dem n¨achsten Befehl, der auf CALL folgt, fortgesetzt wird. Bei den meisten Unterprogrammen werden Informationen mit dem rufenden Programm ausgetauscht. Das Un-terprogramm wird durch Parameter gesteuert und liefert Ergebnisse an das rufende Programm zur¨uck. Unterprogramme k¨onnen ihrerseits wieder Unterprogramme aufrufen. Da Unterprogram-me mit den gleichen Register arbeiten m¨ussen, wie das rufende Programm, k¨onnen nach dem Unterprogramm Register ver¨andert sein. Im folgenden Beispiel bildet ein Unterprogramm den Mittelwert aus AX und BX und gibt ihn in AX zur¨uck.

.model small .stack 100h .code

start:

mov ax,15 ; Vorbereitung des Unterprogrammaufrufs mov bx,19 ; ¨Ubergabe der Parameter in AX und BX CALL Mittelwert_ax_bx ; Unterprogrammaufruf

mov ah,4ch ; Programmende

int 21h ;

81

82 KAPITEL 10. UNTERPROGRAMME PROC Mittelwert_ax_bx

add ax,bx ; Summe aus ax und bx nach ax shr ax,1 ; durch zwei teilen

ret ; Return: R¨ucksprung ENDP Mittelwert_ax_bx

END Start

Die Verwendung von PROC und ENDP ist nicht notwendig, ist aber sehr zu empfehlen. F¨ur die Ubergabe von Parametern und Ergebnissen gibt es verschiedene M¨¨ oglichkeiten:

Ubergabe in Registern¨ Einfach und gut, ¨ublich in reinen Assemblerprogrammen, z.B. BI-OS, DOS. M¨oglich ist auch die R¨uckgabe von Ergebnissen in Flags. Nachteil: Anzahl und Umfang der Parameter begrenzt. Bei großen Datenstrukturen muss man diese in Puffer-speichern halten und Zeiger auf diese Daten in Registern ¨ubergeben.

Stack¨ubergabe In Hochsprachen implementiert, etwas komplizierter erm¨oglicht aber (fast) unbegrenzte ¨Ubergabe

Uber globale Variable¨ f¨uhrt zu Abh¨angigkeiten von Variablendefinitionen im rufenden Pro-gramm. R¨uckgabe der Ergebnisse = Seiteneffekt. Schlecht und nur eine Notl¨osung!

Der R¨ucksprung an die richtige Stelle im rufenden Programm wird auf folgende Art gesichert:

CALL speichert die Adresse des n¨achsten Befehles nach CALL, die R¨ucksprungadresse, im rufenden Programmst¨uck auf den Stack.

RET holt die R¨ucksprungadresse vom Stack und l¨ad sie in das Instruction Pointer Register (IP), so dass dort fortgesetzt wird.

1

Ein wichtiges Thema ist das Ver¨andern von Registern durch Unterprogramme. Es gibt verschie-dene M¨oglichkeiten damit umzugehen:

Unterprogramm ¨andert keine Register Die sichere Methode: Alle im Unterprogramm be-nutzten Register werden zu Beginn des Unterprogramms auf den Stack gerettet und vor dem Return-Befehl wieder hergestellt. Dabei werden allerdings auch die Register gesichert, die im rufenden Programm gar nicht mehr gebraucht werden. Dies verlangsamt das Pro-gramm. Register f¨ur die Ergebnisr¨uckgabe m¨ussen ausgenommen werden.

Unterprogramm k¨ummert sich nicht um ver¨anderte Register Die intelligente Metho-de: Der Programmierer muss sich im rufenden Programm um die Rettung von Registe-rinhalten k¨ummern, allerdings nur, wenn diese Register noch gebraucht werden. Erfordert Aufmerksamkeit, f¨uhrt aber zu den schnellstm¨oglichen Programmen. Die richtige Wahl bei zeitkritischen Programmen.

1 CALL und RET sind also spezielle Sprungbefehle. In einer 16-Bit-Umgebung codiert der Assembler sie je nach Speichermodell als NEAR oder FAR.

83 Registergruppen Dies ist ein Kompromiss aus den beiden ersten L¨osungen: Ein Teil der Re-gister darf frei im Unterprogramm ver¨andert werden, der Rest muss gesichert und wieder-hergestellt werden. In Hochsprachen verwendet.

Tips zum guten Stil

Ein gutes Unterprogramm...

• erledigt eine Aufgabe und nur eine

• ist so kurz wie m¨oglich und so lang wie n¨otig (z.B. max. 100 Zeilen)

• beginnt mit Kommentaren: Aufgabe des Unterprogrammes, ¨Ubergabe der Parameter, ver¨anderte Register, Anmerkungen des Bearbeiters

• kann alleinstehend ¨ubersetzt und verstanden werden

• hat einen treffenden Namen

Kapitel 11

Die Gleitkommaeinheit

Die Gleitkommaeinheit, engl. floating point unit, FPU, ist eine relativ eigenst¨andige Verarbei-tungseinheit des Prozessors. Sie verf¨ugt ¨uber einen eigenen Befehlssatz und eigene Register und sie kann parallel zum Hauptprozessor arbeiten. Die SSE-Verarbeitungseinheiten (ab Pentium III) k¨onnen mehrere Gleitkommazahlen parallel verarbeiten.

11.1 Gleitkommazahlen

Die Gleitkommaeinheit unterst¨utzt drei Gleitkommaformate, die in Abb.11.1 dargestellt sind.

Intern wird immer im 80-Bit-Format gerechnet, die anderen Formate werden beim Laden in den Gleitkommastack in dieses Format umgewandelt. Alle Gleitkommaformate bestehen aus den Anteilen Vorzeichen, Exponent und Mantisse.

Abbildung 11.1: Die unterst¨utzten Gleitkommaformate