Assembler-Programmierung für x86-Prozessoren/ Stringbefehle
Erscheinungsbild
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