GEHNIO |
|
> Home > Algorithmen > Datenstrukturen > Maschinenmodelle > Probleme > Themen > Mindmaps > Aufgaben > Programmierung > Facharbeit > Abitur > Projekte > Informatik-AG > News > Impressum |
1. EinleitungIn diesem Themenheft wird die Assembler-Programmierung unter PASCAL mit der asm-Anweisungen erläutert.Die Assebler-Programmierung unter PASCAL hat der Vorteil, dass man sehr komfortable arbeiten kann und viele Konzepte von PASCAL weiterverwendet kann. Für die Assembler-Programmierung unter PASCAL vereinbaren wir folgende Programmierkonventionen. 2. ProgrammierkonventionenDie Eingabe und Ausgabe unserer Assembler-Programme soll über die komfortablen Eingabe- und Ausgabeanweisungen von PASCAL geschehen. Wir verwenden also gewöhnliche Integer-Variablen und die READLN() und WRITELN() - Anweisungen. Die Variablen für die Ausgaben entsprechens Ausgabe1, Ausgabe2 usw. Benenne, die Variablen für die Ausgaben entsprechens Ausgabe1, Ausgabe2 usw. Durch diese Vorgehensweise sparen wir uns vor allem komplizierte und kritische Speicherzugriffe, wie dies sonst bei der Assemblerprogrammierung üblich ist. Eine Assemblerprogramm in PASCAL hat dann folgenden Aufbau:
Uses wincrt; Label M1, M2 M3; {hier werden die Label deklariert} Var Eingabe1, Eingabe2 :Integer; Ausgabe1, Ausgabe2, Ausgabe3 : Integer; {Ein- und Ausgabevariablen} Begin {Beginn des Pascal-Programms} asm {Beginn des Assembler-Programms}
end; {Ende des Assembler-Programms} end. {Ende des Pascal-Programms} 3. Die CPU-RegisterBei der Assembler-Programmierung werden interne Speicherbausteine des Prozessors (z.B. des 8086-Prozessors) angesprochen und verwaltet, um Daten bei der Abarbeitung eines Programms zwischen den Bauteilen des Prozessors transportieren und zwischenspeichern zu können. Diese sogenannten Regiester befinden sich im Innern des Prozessors, so dass ein blitzschneller Zugriff auf die Daten gewährleistet ist.Wir wollen zunächst die sogenannten Allzweckregister besprechen, die sehr häufig bei der Assembler.Programmierung verwendet werden. 3.1. AllzweckregiesterDie Allzweckregiester setzen sich aus dem Akkumulator (AX), dem Basisregiester (BX), dem Zählregister (CX) und dem Datenregiester (DX) zusammen. Bei allen Regiestern des 8086-Prozessors handelt es sich um 16-Bit-Regiester. Nach der Binärlogik kann ein Wertebereich bis 216 in jedem Regiester gespeichert und verarbeitet werden.3.2. Der Akkumulator (AX)Der Akkumulator (auch AX-Regiester genannt) wird hauptrsächlich bei allen arithmetischen Operationen eingesetzt. Standartmäßig muß es bei der Multiplikation und Division verwendet werden. Der Akkumulator solle aber auch bei Addition, Subtraktion und Vergleichen verwendet werden, weil arithmetischen Aufgaben dadurch effizient bearbeitet werden können.3.3. Das BX-RegisterMöchten Sie den Inhalt des Arbeitsspeichers direkt ansprechen, so müssen Sie das BX-Register verwenden. Das Basis-Register mit der Abkürzung BX erlaubt es uns, direkt auf den Arbeitsspeicher zuzugreifen. Das BX-Register wird dazu als eine Art Zeiger auf den Inhalt des Speichers verwendet. Mit Hilfe dieses Zeigers kann der Inhalt von Speicherzellen direkt gelesen und beschrieben werden, was dieses Register besonders für die Tabellen- und String- Verarbeitung interessant macht.Bei der Verwendung des BX-Registers muß man sich natürlich immer darüber klar sein, auf welche Speicherzelle das Register gerade zeigt. Man kann diesem Register natürlich auch Werte zuweisen, z.B. den Anfang (die Basis) eines reservierten Speicherbereichs. So wird z.B. durch die Assembleranweisung MOV BX, offset MeinString das BX-Register auf den Anfang eines Strings gesetzt. 3.4.Das CX-RegisterDas Count- oder Zähler-Register ist der Spezialist, wenn es um den Einsatz von Schleifen geht.So kann man z.B. mit Hilfe des LOOP-Befehls und dem CX-Register sehr komfortabel eine Schleife Programmieren. Beispiel: Schleifenanfang: {Das ist ein Label den Anfang der Schleife} {Hier werden die Befehle eingetragen, die wiederholt ausgeführt werden!} {CX kann dabei manipuliert werden, z.B. mit DEC CX bzw. INC CX} loop Schleifenanfang: {Solange Cx ungleich null springe zum Schleifenanfang!} Das folgende Beispielprogramm zeigt die Verwendung des CX-Registers anhand eines einfachen Algorithmus zur Berechnung des Summe der ersten n natürlichen Zahlen. program assemblertest; uses wincrt; LABEL Anfang; var Eingabe, Ausgabe : integer; begin readln(Eingabe); {Hier beginnt der eigentliche Assemblercode!} asm
MOV CX,Eingabe; Anfang: ADD AX, CX; {AX:=AX+CX} DEC CX; {Decrementieren des CX-Registers CX:=CX-1;} CMP CX,0; {Vergleiche CX mit 0} JNE Anfang; {Jump if not equal} MOV Ausgabe,AX; end; {Hier endet der Assemblercode!} writeln(Ausgabe); end. 3.5.Das DX-RegisterDieses Register wird besonders in Verbindung mit 32-Bit-Multiplikations- und Divisionsoperationen genutzt. Das DX-Register wird hier zusammen mit dem AX-Register verwendet. Beispiel:MOV AX, Laenge {Der erste Operand muß sich im Akkumulator befinden} MUL Breite {Der zweite Operant muß beim Mul-Befehl angegeben werden} Das Ergebnis steht dann mit dem HIGH-Teil im DX-Register, mit dem LOW-Teil im Akkumulator. 3.6.Weitere RegisterSelbsverständlich gibt es noch zahlreiche weitere Register.Dies sind vor allem
4.Das Format einer Assembler-ZeileDamit der Assembler die Befehle und dazugehörige Operanden auseinanderhalten kann, haben die Zeilen im Quelltext folgendes Format. Label: Befehl/Anweisung Operanden; {Kommentar} Beispiele Addiere: ADD AX, laenge; {Die Länge wird zum Akkuinhalt addiert}MOV CX, 200; 5.Verschiebe und Ladebefehle5.1.Der Move-Befehl
Beispiele
MOV CX,Zaehler; {CX:=Zaehler} 5.2.Der Tauschbefehl XCHG
Dieser Befehl Tauscht den Inhalt von Operand1 mit dem Inhalt von Operand2. Es ist ein sehr nützlicher Befehl für Sortierroutinen. 6.Mathematische GrundbefehleWie das bei vielen Prozessoren der Fall ist, beherrscht auch der 8086-Prozessor zunächst nur einfache mathematische Befehle wie z.B. Addition, Subtraktion, Multiplikation und Division. Dies ist jedoch ausreichend, weil sich höhere mathematische Operationen, wie z.B. Potenzfunktion oder Wurzelfunktion aus diesem Grundrechenart ableiten lassen.6.1.Der Additionsbefehl ADD
ADD Zaehler,10; {Zaehler:=Zaehler+10} ADD Al,11; {Al:=Al+11} 6.2. DER SUBTRAKTIONSBEFEHL SUBDer SUB-Befehl subtrahiert den Inhalt des Quelloperanden vom Inhalt des Zieloperanden und legt das Ergebnis im Zieloperanden ab. Beispiele: SUB AX, 2000; {AX := AX - 2000} SUB Zaehler,10; {Zaehler := Zaehler - 10} SUB Al,11; {Al := Al - 11} 6.3. DER MULTIPLIKATIONBEFEHL MULMUL Quelle; {AX := AL * Quelle} Der Befehl MUL multipliziert den Wert im Quelloperanden mit dem Wert im Akkumulator. Als Quelloperand kann ein CPU-Register oder eine Variable verwendet werden. Beim MUL-Befehl m�ssen wir zwischen einer Byte- und einer Wort-Multiplikation unterscheiden. 6.3.1. Die Byte-MultiplikationDie Bytemultiplikation multipliziert zwei vorzeichenlose 8-Bit-Werte miteinander und legt das Ergebnis im AX-Register ab. Ein Operand mu� sich dabei im AL-Register gefinden (LOW-Teil des Akkumulators) Der zweite Operand, der aus einem 8-Bit-Register oder einer 8-Bit-Speicherstelle bestehen mu�, wird beim Aufruf des Mul-Befehls mit angegeben.Beispiel: MOV AL,50; {AL := 50} MOV BH,100; {BH := 100} MUL BH {AX := AL * BH} 6.3.2. Die Wort-MultiplikationDie Wort-Multiplikation multipliziert zwei vorzeichenlose 16-Bit-Werte miteinander und legt das Ergebnis im Registerpaar DX/AX ab. Der h�herwertige Wert steht dabei im DX-Register, der niederwertige Wert im AX-Register. Ein Operand mu� sich im AX-Register befinden. Der zweite Operand, der aus einem 16-Bit Register oder einer Wort-Speicherstelle bestehen mu�, wird beim Aufruf des Mul-Befehls mit angegeben.6.4. DER DIVISIONSBEFEHL DIVDIV Quelle; {AX := AX DIV Quelle} Der Befehl DIV dividiert den Wert im Zieloperanden durch den Wert im Quelloperanden. Der Zieloperand ist bei einer Byte-Division standardm��ig das AX-Register, bei einer Wort-Division das Registerpaar AX/DX. Als Quelloperand kann ein CPU-Register oder ein Speicheroperand verwendet werden. 6.4.1. Die Byte-DivisionDie Byte-Division dividiert den Inhalt des Ax-Registers durch einen 8-Bit-Wert. Das Ergebnis wird im AX-Register abgelegt. Der Quotiont, also das ganzzahlige Ergebnis der Division, befindet sich im AL-Register (LOW-Teil des Akkumulators), der Divisionsrest (vgl. Modula-Funktion bei Pascal) im AH-Register (HIGH-Teil des Akkumulators). 6.4.2. Die Wort-DivisionDie Wort-Division dividierrt den Inhalt des Registerpaar DX/AX durch einen 16-Bit-Wert. Das ganzzahlige Ergebnis der Division wird im AX-Register abgelegt, der Divisionsrest im DX-Register.6.5. InkrementierenZum Inkrementieren, also zum Heraufz�hlen eines Registerinhalts gibt es einen speziellen Befehl. Der Inkrement-Befehl addiert den Wert 1 zum Ziel. INC Ziel; {Ziel := Ziel + 1} 6.6. DekrementierenZum Dekrementieren, also zum Herabz�hlen eines Registerinhalts gibt es einen speziellen Befehl. Der Dekrement-Befehl subtrahiert den Wert 1 vom Ziel. DEC Ziel; {Ziel := Ziel - 1} 7. Sprung- und Schleifenbefehle7.1. Der unbedingte SprungJMP Ziel; Der Jump-Befehl bewirkt einen Sprung auf eine Adresse im Programm, die mit dem Zieloperanden angegeben wird. Der Zieloperand ist dabei meistens ein Label. 7.2. Bedingte Spr�nge - IF-THEN in AssemblerBedingte Spr�nge werden durch eine Kombination aus Vergleichs-Befehl (CMP) und Sprung-Befehl realisiert. Wir werden uns auf die wichtigsten Befehle beschr�nken. Jxxx Ziel; {Springe, wenn die Bedingung erf�llt ist, zum Ziel} 7.3. Der Wiederderholungsbefehl LOOPLOOP Ziel; {Verzweige so lange zum Ziel, bis CX-Register=0}Der LOOP-Befehl verzeigt so lange zu dem Zieloperanden (z.B. Label), bis das CX-Register den Wert null aufweist. Der Loop-Befehl vermindert dazu bei jedem Aufruf das CX-Register um den Wert 1 und kontrolliert anschlie�end dessen Inhalt. Wenn das CX-Register den Wert null aufweist, dann wird der n�chste Befehl nach der LOOP-Anweisung verarbeitet. Beispiel: program assemblertest; uses wincrt; LABEL Anfang; var Eingabe1, Eingabe2, Ausgabe1 : integer; begin readln(Eingabe1); readln(Eingabe2); {Hier beginnt der eigentliche Assemblercode!} asm MOV AX,Eingabe1; MOV CX,Eingabe2; DEC CX; {CX := CX - 1} Anfang: ADD AX, Eingabe1; LOOP Anfang; {Solange CX ungleich Null Springe zum Anfang} MOV Ausgabe1,AX; end; {Hier endet der Assemblercode!} writeln(Ausgabe1); end. 8. Aufgaben zum ThemaAufgabe 1:Schreiben Sie ein Assembler-Programm unter PASCAL, dass zu einer eingegebenen positiven ganzen Zahl n das Quadrat berechnet.Aufgabe 2:Schreiben Sie ein Assembler-Programm unter PASCAL, das die Summe der ersten n nat�rlichen Zahlen berechnet und ausgibt.S := 1 + 2 + 3 + ... + (n-3) + (n-2) + (n-1) +n Aufgabe 3:Schreiben Sie ein Assembler-Programm unter PASCAL, dass bei einer eingegebenen positiven ganzen Zahl n �berpr�ft, ob diese ungerade oder gerade ist. Das Programm soll dabei "1" ausgeben, wenn die eingegeben Zahl gerade war und "0", wenn die eingegebene Zahl ungerade war.Aufgabe 4:Schreiben Sie ein Assembler-Programm unter PASCAL, dass bei einer eingegebenen positiven ganzen Zahl n �berpr�ft, ob es sich bei der Zahl um eine Quadratzahl handelt oder nicht. Das Programm soll dabei "1" ausgeben, wenn die eingegeben Zahl eine Quadratzahl war und
|
© 2002 Gesamtschule Duisburg-Hamborn/Neumühl. |