Übungen

Übung 1 (17.04.2000) RZ3

Entwickeln Sie unter Beachtung der nachfolgenden Randbedingungen ein EXE-Programm zum dezimalen Einlesen und Ausgeben einer Integer-Zahl :

Übung 2 (02.05.2000) RZ3

Entwickeln Sie unter Beachtung der nachfolgenden Randbedingungen eine EXE-Programm zur Addition zweier Matrizen :

Übung 3 (15.05.2000) RZ3

Übersetzen Sie das nachfolgende Pascal-Programm in ein äquivalentes Assemblerprogramm (8086,EXE) :
Program Uebung3;

Uses Crt;

Var Screen : Array[0..24,0..79] Of Integer Absolute $B800:$0000;
    I,J    : Integer;

Procedure MultiSwap(Count:Integer; Var X,Y:Integer);

Var Z : Integer;

Begin
  While Count > 0 Do Begin
    Z := X;
    X := Y;
    Y := Z;
    Count := Count-1
  End
End;

Begin
  For I := 0 To 24 Do 
    For J := 0 To 79 Do
      MultiSwap(I*J,Screen[I,J],Screen[24-I,79-J]);
  Repeat Until ReadKey = #13
End.
Dies ist sicher keine "Musterlösung", jedoch eine Lösung, die in der Klausur mit dem Urteil "sehr gut" benotet werden würde :
; Program Uebung3;

STAPEL     SEGMENT STACK
           DW   256 DUP (?)
STAPEL     ENDS

; Uses Crt;

CRT        SEGMENT
           ASSUME CS:CRT

READKEY    PROC FAR
           MOV  AH,8
           INT  21h
           RET
READKEY    ENDP

CRT        ENDS

; Var Screen : Array[0..24,0..79] Of Integer Absolute $B800:$0000;

SCREEN     SEGMENT AT 0B800h 
           DW   2000 DUP (?)
SCREEN     ENDS

;     I,J    : Integer;

DATA       SEGMENT
I          DW   ?
J          DW   ?
DATA       ENDS

CODE       SEGMENT
           ASSUME CS:CODE,DS:DATA

; Procedure MultiSwap(Count:Integer; Var X,Y:Integer);

MULTISWAP  PROC

COUNT      EQU  WORD PTR [BP+12]
SEGX       EQU  [BP+10]
OFFX       EQU  [BP+8]
SEGY       EQU  [BP+6]
OFFY       EQU  [BP+4]

           PUSH BP 
           MOV  BP,SP

; Var Z : Integer;

Z          EQU  [BP-2]

           SUB  SP,2

; Begin

           PUSH DS
           PUSH AX
           PUSH BX

;   While Count > 0 Do Begin

WHILEC:    CMP  COUNT,0          
           JLE  ENDWHILEC

;     Z := X;
           
           MOV  DS,SEGX
           MOV  BX,OFFX
           MOV  AX,[BX]
           MOV  Z,AX

;     X := Y;

           MOV  DS,SEGY
           MOV  BX,OFFY
           MOV  AX,[BX]
           MOV  DS,SEGX
           MOV  BX,OFFX
           MOV  [BX],AX

;     Y := Z;

           MOV  AX,Z
           MOV  DS,SEGY
           MOV  BX,OFFY
           MOV  [BX],AX

;     Count := Count-1

           DEC  COUNT

;   End

           JMP  WHILEC
ENDWHILEC: 

; End;

           POP  BX
           POP  AX
           POP  DS
           MOV  SP,BP
           POP  BP
           RET  10

MULTISWAP  ENDP

; Begin

UEBUNG3    PROC
          
           MOV  AX,DATA
           MOV  DS,AX
           MOV  AX,SCREEN
           MOV  ES,AX

           MOV  I,0

;   For I := 0 To 24 Do 

FORI:      CMP  I,24
           JG   ENDFORI

           MOV  J,0

;     For J := 0 To 79 Do

FORJ:      CMP  J,79 
           JG   ENDFORJ
                      
;       MultiSwap(I*J,Screen[I,J],Screen[24-I,79-J]);

           MOV  AX,I
           MUL  J
           PUSH AX
           PUSH ES
           MOV  AX,I
           MOV  DX,160
           MUL  DX
           MOV  DX,J
           SHL  DX,1
           ADD  AX,DX
           PUSH AX
           PUSH ES
           MOV  AX,I
           NEG  AX
           ADD  AX,24
           MOV  DX,160
           MUL  DX
           MOV  DX,J
           NEG  DX
           ADD  DX,79
           SHL  DX,1
           ADD  AX,DX
           PUSH AX
           CALL MULTISWAP

           INC  J
           JMP  FORJ
ENDFORJ:

           INC  I 
           JMP  FORI
ENDFORI:

;   Repeat Until ReadKey = #13

REPEAT:    CALL READKEY
           CMP  AL,13
           JNE  REPEAT

; End.

           MOV  AX,4C00h
           INT  21h

UEBUNG3    ENDP
        
CODE       ENDS

           END UEBUNG3

Übung 4 (22.05.2000) HS4

Übersetzen Sie die nachfolgenden Assembler-Programmausschnitte (Ziel: COM-Dateien) in Maschinencode :
      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.

Übung 5 (19.06.2000) RZ3

Entwickeln Sie je ein Assembler-Programm zur einfachen Komprimierung und Dekomprimierung von Textdateien gemäß nachfolgender als Pascal-Programme formulierter Spezifikation. Die Lösung muß spätestens zu Beginn der 6. Übung am 03.07.2000 fertiggestellt sein. Der Übungstermin am 19.06.2000 dient damit im wesentlichen zur Bearbeitung der Aufgabe unter individueller Hilfestellung.
Program EasyCode;

Var B : Byte;
    C : Char;
    F : File Of Byte;
    I : Integer;
    S : String;

Begin
  If ParamCount = 0 Then
    Assign(F,'EASYCODE.DTA')
  Else
    Assign(F,ParamStr(1));
  Rewrite(F);
  While Not Eof Do Begin
    ReadLn(S);
    I := 1;
    While I<=Length(S) Do Begin
      C := S[I];
      B := 0;
      While (I<=Length(S)) And (S[I]=C) Do Begin
        I := I+1;
        B := B+1
      End;
      Write(F,B);
      B := Ord(C);
      Write(F,B)
    End;
    B := 0;
    Write(F,B)
  End;
  Close(F)
End.
Program Decode;

Var B1 : Byte;
    B2 : Byte;
    F  : File Of Byte;

Begin
  If ParamCount = 0 Then
    Assign(F,'EASYCODE.DTA')
  Else
    Assign(F,ParamStr(1));
  {$I-} Reset(F); {$I+}
  If Ioresult<>0 Then
    WriteLn('DECODE: Quelle existiert nicht !')
  Else Begin
    While Not Eof(F) Do Begin
      Read(F,B2);
      If B2=0 Then
        WriteLn
      Else Begin
        B1:=B2;
        Read(F,B2);
        Repeat
          Write(Chr(B2));
          B1 := B1-1
        Until B1=0
      End
    End;
    Close(F)
  End
End.
INT 21h MS-DOS Funktionsaufruf
AH Wirkung Eingabe Ausgabe
3Ch Logischen Zugriffskanal definieren (create handle) "Datei anlegen und für Schreib-/Lesezugriffe öffnen" CX = Dateiattribut (0 : keine Attribute)
DS:DX = Adresse Dateiname (nullterminiert)
AX = Nummer I/O-Kanal oder Fehlercode bei gesetztem Carry-Flag
3Dh Logischen Zugriffskanal öffnen (open handle) "Datei für Lese-, Schreib- oder Schreib-/Lesezugriff öffnen" AL=0 : Lesezugriff
AL=1 : Schreibzugriff
AL=2 : Schreib-/Lesezugriff
DS:DX = Adresse Dateiname (nullterminiert)
AX = Nummer I/O-Kanal oder Fehlercode bei gesetztem Carry-Flag
3Eh Logischen Zugriffskanal schließen (close handle) "Datei schließen" BX = Nummer I/O-Kanal  
3Fh Lesen von Datei bzw. Gerät (read file/device) BX = Nummer I/O-Kanal (0 : Standard-Eingabe, 1 : Standard-Ausgabe)
CX = Anzahl der zu lesenden Zeichen
DS:DX = Adresse Eingabepuffer
AX = Anzahl tatsächlich gelesener Zeichen (AX<CX, falls EOF erreicht) oder Fehlercode bei gesetztem Carry-Flag
40h Schreiben auf Datei bzw. Gerät (write file/device) BX = Nummer I/O-Kanal (0 : Standard-Eingabe, 1 : Standard-Ausgabe)
CX = Anzahl der zu schreibenden Zeichen
DS:DX = Adresse Ausgabepuffer
AX = Anzahl tatsächlich geschriebener Zeichen (AX<CX bedeutet Fehler) oder Fehlercode bei gesetztem Carry-Flag

Weitere Informationen zur Dateiverarbeitung unter MS-DOS :

Übung 6 (03.07.2000) RZ3

Entwickeln Sie das Assembler-Programm TOOLBOX.ASM zur Implementierung der Funktionen IFAK, RFAK und COUNT sowie der Prozedur WRITEDEZ.
Program Uebung6;

Const S : String = 'Die letzte Uebungsaufgabe im Sommersemester 2000';

{$L TOOLBOX}

Function IFak(X:Integer):Integer; External;
{ Fakultaetsberechnung iterativ }

Function RFak(X:Integer):Integer; External;
{ Fakultaetsberechnung rekursiv }

Procedure WriteDez(X:Integer); External;
{ Dezimalzahlenausgabe }

Function Count(C:Char; Var S:String):Integer; External;
{ Haeufigkeitsberechnung (von C in S) }

Begin
  WriteDez(IFak(5));
  WriteDez(RFak(5));
  WriteDez(-1*IFak(5));
  WriteDez(-1*RFak(5));
  WriteDez(Count('e',S))
End.