OPERATIONEN MIT OKTETT- / WORT- FOLGEN

 

Befehle für Operationen über Folgen:

- die eine Folge als Quelle und eine als Ziel benützen (MOVSB, MOVSW,

  CMPSB, CMPSW)

- die benützen nur eine Folge als Quelle (LODSB, LODSW)

- die benützen nur eine Folge als Ziel (STOSB, STOSW, SCASB, SCASW)

 

(Move String = MOVS

 Compare String = CMPS

 Load String = LODS

 Store String = STOS

 Scan String = SCAS)

 

Eigenschaften einer Folge:

- Typ der Elemente (Oktett oder Wort) => bezeichnet durch dem letzten

  Buchstabe des Befehls (B=byte, W=word); beide Folgen sind vom gleichen

  Typ

- die Adresse des ersten Elementes - ist eine folgenderweise gegebene

  FAR Adresse

            - in DS:SI - für die Quell-Folge

            - in ES:Di - für die Ziehl-Folge

- Direktion der Durchlauf => ist durch dem Wer von DF (Direktionsflag)

  bezeichnet (wenn 0 - von kleinere Adressen zu größeren, wenn 1 -

  von größere Adressen zu kleineren; siehe CLD, STD)

- Anzahl der Elemente => wenn gebraucht, wird es im CX

  gespeichert

 

Befehle für Datentransfer

 

LODSB - Es wird das Oktett von der Adresse <DS:SI> in Al geladen

            Wenn DF=0, dann inc(SI), sonst dec(SI)

LODSW - Es wird das Wort von der Adresse <DS:SI> in AX geladen

            Wenn DF=0, dann SI:=SI+2, sonst SI:=SI-2

STOSB - Das Oktett von Al wird an die Adresse <ES:DI> gespeichert

            Wenn  DF=0, dann inc(DI), sonst dec(DI)

STOSW - Das Wort von AX wird an die Adresse <ES:DI> gespeichert

            Wenn  DF=0, dann DI:=DI+2, sonst DI:=DI-2

MOVSB - Das Oktett von der Adresse <DS:SI> wird an die Adresse

            <ES:DI> gespeichert.

            Wenn  DF=0, dann SI:=SI+2, DI:=DI+2, sonst dec(SI), dec(DI)

MOVSW - Das Wort von der Adresse <DS:SI> wird an die Adresse

            <ES:DI> gespeichert.

            Wenn  DF=0, dann inc(SI), inc(DI), sonst SI:=SI-2, DI:=DI-2

 

 

Beispiel: Wir haben eine gegebene Quell-Folge (die Elemente sind

 Wörter). Kopieren Sie es in eine andere Ziel-Folge. Wir nehmen an,

 dass wir die Anzahl der Elementen wissen.

 

     mov CX, dim_Reihe

     mov SI, OFFSET Quell_Folge

     mov AX, SEG Quell_Folge

     mov DS, AX

     mov DI, OFFSET Ziel_Folge

     mov AX, SEG Ziel_Folge

     mov ES, AX

     CLD

Wieder:

     LODSW

     STOSW

LOOP Wieder

 

;(oder direkterweise mit MOVSW)

 

 

 

Befehle für Vergleich und Test

 

SCASB - CMP AL, <ES:DI>

            Wenn DF=0, dann inc(DI), sonst dec(DI)

            (veräderte Flags: OF, SF, ZF, AF, PF, CF)

SCASW - CMP AX, <ES:DI>

            Wenn DF=0, dann DI:=DI+2, sonst DI:=DI-2

            (OF, SF, ZF, AF, PF, CF)

CMPSB - CMP <DS:SI>, <ES:DI>

            Wenn DF=0, dann inc(SI), inc(DI), sonst dec(SI), dec(DI)

            (OF, SF, ZF, AF, PF, CF)

CMPSW - CMP <DS:SI>, <ES:DI>

            Wenn DF=0, dann SI:=SI+2, DI:=DI+2, sonst SI:=SI-2, DI:=DI-2

            (OF, SF, ZF, AF, PF, CF)

 

 

Beispiel:  

 Es ist eine Okett-Folge gegeben. Finden Sie den letzten "0" Charakter.

 

 

     ;... es sind alle Daten über der Ziel-Folge geladen

     MOV AL, '0'

     MOV CX, Dim_Folge

     STD

suche_weiter:     ; wir suchen weiter...

     SCASB

     JE Gefunden

LOOP suche_weiter

     ...

Gefunden:

     DEC DI     ; wir kehren zurück zum Charakter der noch

                        ; vor dem Inkrementierung von DI gefunden war

 

 

 

Wiederholte Ausführung einer Operation auf Folgen

 

Prefix_Befehl Instruktion_über_Reihe

 

  ist gleich wie

 

Wieder:

       Instruktion_über_Reihe

       LOOP Wieder

 

... wo Prefix_Befehl kann REP (gleich wie REPE - Repeat While Equal -),

REPZ (Repeat While Zero) sein, der die Befehle SCAS_ oder CMPS_

wiederholt bis CX 0 wird, oder bis es eine Ungleichartigkeit

getroffen wird ( => ZF=0)

... oder kann REPNE (Repeat While Not Equal) oder REPNZ (Repeat

While Not Zero) sein, der die Befehle SCAS_ oder CMPS_ wiederholt

bis CX 0 wird, oder bis es eine Gleichheit getroffen wird ( => ZF=1)

 

Anmerkungen:

- Bei der Operationen über Folgen werden die Flags nicht verändert

  nach der veränderungen von Register SI, DI oder CX

- LODS_, STOS_, MOVS_ - verändert kein Flag, weil SCAS_ und CMPS_

  verändert die Flags dem durchgeführte Komparationsbefehl

  entsprechend.

 

 

**********************************************************************

 

Ergänzungen

 

- Man sollte doch auch den Norton Guide lesen

 

- Schleife:

 

LOOP:

Allgemeine Form:

 

     Rückkehr_Label:

         Befehle

     LOOP Rückkehr_Label

    

- im allgemeinen Fall werden die Befehle CX-mal (der Wert,

  der schon nach vorne in CX hingelegt war) wiederholt

- wenn die Kondition für Wiederholung komplexer ist kann man die

  andere warianten benützen LOOPE (LOOP While Equal), LOOPNE (LOOP

  While Not Equal) (wenn vor dem LOOP* haben wir eine arithmetische

  Instruktion, Komparation, usw. - wird man von der Schleife

  herauskommen wenn CX 0 wird oder wenn man eine "Ungleichartigkeit"

  trifft, bei LOOPE, bzw. eine "Gleichheit" für LOOPNE)

(siehe Beispiel.asm)

 

 

- Unterprogrammen

 

 

Name_Unterprogramm PROC

    Befehle...

    RET

Name_Unterprogramm ENDP

 

Es wird (im allgemeinen) mit

  CALL Name_Unterprogramm

gerufen.

 

 

Beispiel:

; Es ist eine Oktett-Folge gegeben. Bilden Sie eine neue Folge,

; die wird von der erste Reihe die Elemente enthalten die mehrere

; 1-Bits als 0-Bits haben.

 

 

assume ds:data,cs:code

 

data segment

 

     a db 47h,65h,35h,41h

     d equ $-a

     r db d dup(0h)

 

data ends

code segment

 

start:

 

     ; die nötige Adressen in Register laden

     mov ax,data

     mov ds,ax

     mov es,ax

     mov si,offset a

     mov di,offset r

     mov cx,d

     cld

 

wieder:

 

     lodsb

     call zaehlen

 

     mov bh,8

     sub bh,bl  ;bh=nr 0, bl=nr 1

     cmp bl,bh

     jbe nichtstun

     stosb

 

nichtstun:

loop wieder

 

     jmp ende

 

zaehlen proc                 ; zählt die Bits 1 von Al

     push cx                    ; CX speichern

     mov cx,8

     xor bx,bx

noch:

     rcl al,1

     adc bl,0

loop noch                     ;in BL haben wir die Anzahl der Bits 1

 

     pop cx                     ; CX zurücklegen

     ret                           ; Rückkehr vom Unterprogrammm

zaehlen endp

 

ende: 

     mov ax,4C00h

     int 21h

code ends

end start