Das nachfolgende Dialogbeispiel möge die Aufgabenstellung verdeutlichen :
Moin Moin - Assembler ist eine schön bittige Programmiersprache A 3 B 2 C 2 D 0 E 7 F 0 G 2 H 2 I 7 J 0 K 0 L 1 M 5 N 4 O 3 P 2 Q 0 R 5 S 5 T 3 U 0 V 0 W 0 X 0 Y 0 Z 0
Zum Testen dient ein zu entwickelndes Hauptprogramm, welches beliebig viele Integer-Werte über die Standardeingabe einliest (Abbruchkriterium sei die Zahl -32768), und anschließend den größten und kleinsten Wert, sowie den Mittelwert in der Form ganzzahliges Ergebnis und (ganzzahligen) Rest ausgibt.
Tips für die Toolbox-Routine : Jedes via DOS-Funktion 8 (MOV AH,8 INT 21h) ohne Echo eingelesenes Zeichen wird entweder sofort verarbeitet (gültiges Zeichen laut Syntaxdiagramm) oder ignoriert (ungültiges Zeichen laut Syntaxdiagramm). Zur Verarbeitung gehört auch das Echo gültiger Zeichen über die Standardausgabe. Das Eingabeende erfolgt durch Drücken der RETURN-Taste. Eventuell entstehende Zahlenüberläufe wie z.B. 32768 dürfen ignoriert werden.
MOV DL,43h ; Offsetadresse 100
MOV DL,21h
MOV DX,4321h
MOV OPA,DX
MOV DX,OPA
MOV TABL[SI],DX
MOV DX,TABL[SI]
MOV OPA,4321h
MOV TABL[SI],4321h
INT 20h
CALL UP ; Offsetadresse 300
...
UP PROC ; Offsetadresse 400
...
UP ENDP
UP PROC ; Offsetadresse 200
...
UP ENDP
...
CALL UP ; Offsetadresse 300
JE MARKE ; Offsetadresse 200
...
MARKE:... ; Offsetadresse 230
MARKE:... ; Offsetadresse 1D0
...
JE MARKE ; Offsetadresse 200
In allen zugrundeliegenden Assembler-Programmen stehen ab der Offsetadresse 150 jeweils folgende Daten :
OPA DW ? OPB DB ? OPC DW ? TABL DW 10 DUP (?)Hinweis : Alle Offsetadressen sind in hexadezimaler Form angegeben.
Program Aufgabe4;
Function Multiply(X,Y:Integer):Integer;
Begin
If Y = 1 Then Multiply := X
Else Multiply := Multiply(X,Y-1) + X
End;
Procedure Divide(X,Y:Integer;Var Q,R:Integer);
Begin
If X >= Y Then Begin
Divide(X-Y,Y,Q,R);
Q := Q+1
End Else Begin
Q := 0;
R := X
End
End;
Var hX, hY, hQ, hR : Integer;
Begin
{$I-}
Repeat
Write('1. Operand : '); ReadLn(hX)
Until (IoResult = 0) And (hX > 0);
Repeat
Write('2. Operand : '); ReadLn(hY)
Until (IoResult = 0) And (hY > 0);
{$I+}
WriteLn(hX,' * ',hY,' = ',Multiply(hX,hY));
Divide(hX,hY,hQ,hR);
WriteLn(hX,' / ',hY,' = ',hQ,' Rest ',hR)
End.
type BobMover = record
positionx : word;
positiony : word;
lastx : word;
lasty : word;
firstspeedx : integer;
firstspeedy : integer;
lastspeedx : integer;
lastspeedy : integer;
bobscount : byte;
end;
Interessant ist es hier, daß wir uns in einem Rahmen bewegen, den ich auf die Koordinaten 2/2 und 290/170 festlegen möchte. Wir haben also eine Startkoordinate,
vorgegeben in positionx und positiony. Wir haben eine Bewegungsgeschwindigkeit firstspeedx und firstspeedy, die zur Bewegung immer auf die Koordinaten
aufaddiert werden müssen. Sollten wir nun im Verlauf auf einen Rand stoßen, so ist die Bewegungsgeschwindigkeit einfach umzudrehen (z.B. durch Multiplikation
mit -1). So denn haben wir noch den Punkt bobscount, schließlich wollen wir zwei Schlangen darstellen, die sich in der Anzahl der Bobs jeweils aus der Konstante MaxBobs ergeben. Fangen wir mit der Darstellung an, so geben wir erst den ersten, dann den zweiten Bob aus und so weiter, wobei sich die Abstände der einzelnen Bobs jeweils aus der Geschwindigkeit ergeben, d. h. der erste Bob erscheint an positionx+0*firstspeedx und positiony+0*firstspeedy, der zweite analog an positionx+1*firstspeedx und positiony+1*firstspeedy. Achtet auch beim Aufbau darauf, daß wir uns dem Bildschirmrand nähern könnten. Da unsere Schlange aber auch ein Ende haben soll, müssen wir irgendwann anfangen, die Bobs auch wieder zu löschen! Dazu haben wir einmal den Punkt bobscount, wo eben halt alle vorhandenen mitgezählt werden. Wir haben auch lastx, lasty, lastspeedx und lastspeedy, womit wir den gleichen Spaß wie mit dem Kopf der Schlange (also dem führendem Bob) noch einmal machen müssen, sprich Koordinaten und Bewegungsgeschwindigkeit errechnen und auf den Rahmen achten.
{$X+}
program Shadebobs;
uses crt;
const BobMatrix : array[0..27,0..27] of byte = (
(0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,1,1,1,2,2,7,7,2,2,1,1,1,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,1,1,2,2,2,1,2,7,7,2,1,2,2,2,1,1,0,0,0,0,0,0),
(0,0,0,0,0,1,2,2,1,1,1,1,2,7,7,2,1,1,1,1,2,2,1,0,0,0,0,0),
(0,0,0,0,1,2,1,1,1,1,1,2,7,7,7,7,2,1,1,1,1,1,2,1,0,0,0,0),
(0,0,0,1,2,1,1,1,1,1,1,2,7,7,7,7,2,1,1,1,1,1,1,2,1,0,0,0),
(0,0,1,2,1,1,1,1,1,1,1,2,7,7,7,7,2,1,1,1,1,1,1,1,2,1,0,0),
(0,0,1,2,1,1,1,1,1,1,2,7,7,8,8,7,7,2,1,1,1,1,1,1,2,1,0,0),
(0,1,2,1,1,1,1,1,1,1,2,7,7,8,8,7,7,2,1,1,1,1,1,1,1,2,1,0),
(0,1,2,1,1,1,1,1,1,2,7,7,8,8,8,8,7,7,2,1,1,1,1,1,1,2,1,0),
(0,1,2,1,1,1,1,2,2,7,7,8,8,9,9,8,8,7,7,2,2,1,1,1,1,2,1,0),
(1,2,1,1,2,2,2,7,7,7,8,8,9,9,9,9,8,8,7,7,7,2,2,2,1,1,2,1),
(1,2,2,2,7,7,7,7,7,8,8,9,9,9,9,9,9,8,8,7,7,7,7,7,2,2,2,1),
(1,7,7,7,7,7,7,8,8,8,9,9,9,9,9,9,9,9,8,8,8,7,7,7,7,7,7,1),
(1,7,7,7,7,7,7,8,8,8,9,9,9,9,9,9,9,9,8,8,8,7,7,7,7,7,7,1),
(1,2,2,2,7,7,7,7,7,8,8,9,9,9,9,9,9,8,8,7,7,7,7,7,2,2,2,1),
(1,2,1,1,2,2,2,7,7,7,8,8,9,9,9,9,8,8,7,7,7,2,2,2,1,1,2,1),
(0,1,2,1,1,1,1,2,2,7,7,8,8,9,9,8,8,7,7,2,2,1,1,1,1,2,1,0),
(0,1,2,1,1,1,1,1,1,2,7,7,8,8,8,8,7,7,2,1,1,1,1,1,1,2,1,0),
(0,1,2,1,1,1,1,1,1,1,2,7,7,8,8,7,7,2,1,1,1,1,1,1,1,2,1,0),
(0,0,1,2,1,1,1,1,1,1,2,7,7,8,8,7,7,2,1,1,1,1,1,1,2,1,0,0),
(0,0,1,2,1,1,1,1,1,1,1,2,7,7,7,7,2,1,1,1,1,1,1,1,2,1,0,0),
(0,0,0,1,2,1,1,1,1,1,1,2,7,7,7,7,2,1,1,1,1,1,1,2,1,0,0,0),
(0,0,0,0,1,2,1,1,1,1,1,2,7,7,7,7,2,1,1,1,1,1,2,1,0,0,0,0),
(0,0,0,0,0,1,2,2,1,1,1,1,2,7,7,2,1,1,1,1,2,2,1,0,0,0,0,0),
(0,0,0,0,0,0,1,1,2,2,2,1,2,7,7,2,1,2,2,2,1,1,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,1,1,1,2,2,7,7,2,2,1,1,1,0,0,0,0,0,0,0,0),
(0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0));
const MaxBobs : byte = 64;
type BobMover = record
positionx : word;
positiony : word;
lastx : word;
lasty : word;
firstspeedx : integer;
firstspeedy : integer;
lastspeedx : integer;
lastspeedy : integer;
bobscount : byte;
end;
var BobSnake1,
BobSnake2 : BobMover;
{$L SBASM}
procedure Grafik_Modus; assembler;
asm
mov ax,13h
int 10h
end;
procedure Text_Modus; assembler;
asm
mov ax,03h
int 10h
end;
procedure Neue_Palette; assembler;
asm
mov dx,3c8h
xor al,al
out dx,al
inc dx
mov cx,256
xor ah,ah
@loop1:
xor al,al
out dx,al
mov al,ah
out dx,al
xor al,al
out dx,al
cmp ah,63
jae @loop2
inc ah
@loop2:
loop @loop1
end;
procedure Bob_setzen(x,y:word;matrix:pointer); external;
procedure Bob_loeschen(x,y:word;matrix:pointer); external;
procedure Bob_berechnen(bobrecord:pointer); external;
procedure Bob_bewegen;
begin
bobsnake1.positionx:=10;
bobsnake1.positiony:=10;
bobsnake1.lastx:=10;
bobsnake1.lasty:=10;
bobsnake1.firstspeedx:=2;
bobsnake1.firstspeedy:=-2;
bobsnake1.lastspeedx:=2;
bobsnake1.lastspeedy:=-2;
bobsnake1.bobscount:=1;
bobsnake2.positionx:=250;
bobsnake2.positiony:=160;
bobsnake2.lastx:=250;
bobsnake2.lasty:=160;
bobsnake2.firstspeedx:=-1;
bobsnake2.firstspeedy:=2;
bobsnake2.lastspeedx:=-1;
bobsnake2.lastspeedy:=2;
bobsnake2.bobscount:=1;
repeat
bob_setzen(bobsnake1.positionx,bobsnake1.positiony,@bobmatrix);
bob_setzen(bobsnake2.positionx,bobsnake2.positiony,@bobmatrix);
bob_berechnen(@bobsnake1);
bob_berechnen(@bobsnake2);
if bobsnake1.bobscount >= maxbobs then bob_loeschen(bobsnake1.lastx,
bobsnake1.lasty,
@bobmatrix);
if bobsnake2.bobscount >= maxbobs then bob_loeschen(bobsnake2.lastx,
bobsnake2.lasty,
@bobmatrix);
until keypressed;
while keypressed do readkey
end;
begin
Grafik_Modus;
Neue_palette;
Bob_bewegen;
Text_Modus;
end.