Zum Inhalt springen

Assembler-Programmierung für x86-Prozessoren/ Stringbefehle

Aus Wikibooks



Maschinensprache-Befehle zur Stringverarbeitung

[Bearbeiten]

Die CPU der 80x86-Familie besitzen spezielle Befehle, mit denen die Verarbeitung von Massendaten, zum Beispiel von Zeichenketten, optimiert werden kann.

Beispiel: Kopieren Byteweise ab Adresse SI nach DI

[Bearbeiten]
        ;
        MOV        CX,40   ; Zeichenanzahl
 SCHL:  MOV        AL,[SI]
        MOV        [DI],AL
        INC        SI
        INC        DI
        LOOP       SCHL

In jedem Schleifendurchlauf muss der Prozessor die gleichen fünf Befehle immer neu lesen und decodieren. Ersetzt man obige Befehle durch

        ;
        MOV        CX,40   ; Zeichenanzahl
        REP MOVSB

wird das Programm kürzer und läuft auch viel schneller.

Hierbei gibt es folgende Befehle:

Übertragungsbefehle:  
MOVSx* Kopiert ein Zeichen von der Adresse ds:si/esi an die Adresse es:di/edi und inkrementiert/dekrementiert** si/esi und di/edi um die Zeichengröße.
LODSx* Kopiert ein Zeichen von der Adresse ds:si/esi in den Akkumulator (al/ax/eax) und inkrementiert/dekrementiert** si/edi um die Zeichengröße.
STOSx* Kopiert ein Zeichen aus dem Akkumulator an die Adresse es:di/edi und inkrementiert/dekrementiert** di/edi um die Zeichengröße.
Vergleichsbefehle:  
SCASx* Vergleicht ein Zeichen von der Adresse es:di/edi mit den Akkumulator (al/ax/eax) und setzt die Flags wie cmp. Inkrementiert/dekrementiert** di/edi um die Zeichengröße.
CMPSx* Vergleicht ein Zeichen von der Adresse ds:si/esi mit einem von der Adresse es:di/edi und setzt die Flags wie cmp. Inkrementiert/dekrementiert** si/esi und di/edi um die Zeichengröße.
Wiederholungspräfixbefehle:  
REP, REPE oder REPZ Führt den folgenden Stringbefehl solange durch und dekrementiert jedes mal cx/ecx um 1, bis cx/ecx null erreicht oder die Zero-Flag nicht gesetzt ist.
REPNE oder REPNZ Führt den folgenden Stringbefehl solange durch und dekrementiert jedes mal cx/ecx um 1, bis cx/ecx null erreicht oder die Zero-Flag gesetzt ist.
 
* x symbolisiert die Zeichengröße. B steht für einen Byte, W für ein Wort und D (im 32 bit Modus) für ein Doppelwort.

** Wenn die Direktion Flag gelöscht ist (erreichbar mit CLD), wird inkrementiert, ist sie gesetzt (erreichbar mit STD) wird dekrementiert.

Beispiel: Das erste Leerzeichen in einem String finden

[Bearbeiten]
       ;
       MOV    CX,SIZE STRING   ; Stringlänge
       CLD                     ; Richtung
       MOV    AL,20H           ; Quelloperand: Leerzeichen
 
       MOV    DI,SEG STRING    ; Segmentadresse
       MOV    ES,DI
       MOV    DI,OFFSET STRING ; Offsetadresse
 
       REPNE SCASB             ; Wiederholen solange ungleich AL
 
       JNZ    xxx              ; bis Ende durchsucht und kein Leerzeichen gefunden
       JZ     yyy              ; bis Ende durchsucht und Leerzeichen gefunden

Beispiel: Zwei Strings auf Gleichheit überprüfen

[Bearbeiten]
       ;
       CLD                      ; In Richtung steigender Adressen vergleichen
       MOV    CX,SIZE STRING1   ; Stringlänge
 
       MOV    SI,SEG STRING1    ; Segmentadresse
       MOV    DS,SI
       MOV    SI,OFFSET STRING1 ; Offsetadresse
 
       MOV    DI,SEG STRING2    ; Segmentadresse
       MOV    ES,DI
       MOV    DI,OFFSET STRING2 ; Offsetadresse
 
       REPE CMPSB               ; Wiederholen solange ungleich AL
 
       JNZ   xxx                ; Strings sind ungleich
       JZ    yyy                ; Strings sind gleich