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 200In 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.