Version 2.0 Aktualisiert: 30.03.04

ADD
Addiere beide Operanden und lege das Ergebnis in den Ersten.
Beispiel:
mov ah,7
mov bh,3
add bh,ah ;bh = 10
AND
Logische UND-Verknüpfung: Der Zieloperand wird bitweise mit dem Quelloperand verknüpft.
AND Ziel,Quelle. Das Ergebnis wird im Zieloperand abgelegt.
Beispiel:
mov ah,10010100b ;ah=10010100b
mov al,10110101b ;al=10110101b
and ah,al ;ah=10010100b
!CALL
Aufruf eines Unterprogramms. Der IP wird auf dem Stack gespeichert, dann wird der IP
mit der Adresse des CALL-Befehls geladem, RET kehrt vom Unterprogramm zurück.
Beispiel:
.
.
call Write ;Das Unterprogramm Write aufrufen
.
.
Write PROC Near ;Deklaration des Unterprogramms
mov ah,09h ;Beispielcode
int 21h
ret ;Zurück
Write ENP ;Ende der Prozedur
CALL ist das Gleiche wie CALL NEAR.
Mit CALL FAR Kann man Prozeduren aufrufen, die nicht im selben Segment liegen.
Bei CALL FAR muss man RETF verwenden.
[E8;FF;9A]
CLC
Clear Carry Flag d.h. CF = 0. Das Carry Flag wird oft als Schalter verwendet,
z.B um Fehler in einem Unterprogramm anzuzeigen. Mit CLC kann das Carry vorher
gelöscht werden.
CLD
Clear Direction Flag: Setzt das Direction Flag auf 0. Damit erfolgen alle
Stringoperationen (z.B. stosb) von links nach rechts (default!!).
CLI
Lösche das Interruptflag. Die extern maskiebaren Interrups werden gesperrt.
D.h. es werden z.B Interrupts die vom Keyboard oder von der Maus erfolgen gesperrt.
Dies ist vor allem dan erforderlich, wenn Zeitkritische Operationen ablaufen, die nicht
gestört werden sollen.
!CMP
Mit CMP werden zwei Operanden verglichen. Die Operanden müssen gleich gross sein,
d.h. entweder Byte/byte oder Word/word. Das Ergebnis des Vergleichs kommt ins Statusregister.
Beispiel:
mov ax,0FFFFh
cmp ax,Var1
je Gleich ;Wenn gleich springe zum Label Gleich
jg Grösser ;Wenn grösser springe zum Label Grösser
jl Kleiner ;Wenn kleiner springe zum Label Kleiner
[3A;3B;3C;3D;38;39;80;81;83]
CMPS
CMPSB (Compare Strings Bytes) / CMPSW (Compare Strings Words)
Mit dem Befehl REP /REPNE können mehrere Daten verglichen werden.
Der Befehl CMPS vergleicht zwei Strings miteinander, wobei der erste Operand über
das Registerpaar DS:SI und der zweite Operand über ES:DI adressiert wird. Nach dem
Vergleich werden SI und DI automatisch erhöht oder bei gesetztem Direction Flag erniedrigt.
Das Ergebnis des Vergleichs kommt ins Statusregister.
Beispiel:
lea di,String1 ;Wenn di auch im Datensegment einfach ES=DS z.B. so: push ds pop es
lea si,String2 ;lea si,String2 entspricht mov si,OFFSET String2
mov cx,12 ;Anzahl der Wiederholungen von REP
rep cmpsb ;Vergleichen
je Weiter ;Springen wenn gleich
!DEC
Decrementieren um 1. D.h. es wird 1 vom Operanden subtrahiert.
Gegenteil: INC.
Beispiel:
mov ah,09h
dec ah ;ah=08h
Oder als LOOP Ersatz (glaub sogar schneller):
mov cx,4
Schleife:
dec cx
.
.
jnz Schleife
Oder um eine Variable zu Dekrementieren:
dec Var1
DIV
Dividiert AX bzw. das Registerpaar DX:AX durch den Divisor.
Divident / Divisor = Quotient Rest
AX (16 Bit) / Operand (8 Bit) = AL AH
DX:AX / Operand (16 Bit) = AX DX
Beispiel:
mov ax,300 ;AX = Divident
mov bh,12 ;bh = Divisor
div bh ;AX/BH = AL(Quotient) AH(Rest)
HLT
Der Befehl HLT (HaLT) hält den Prozessor an bis ein Interrupt erfolgt.
IN
In liest ein Byte oder Word aus einem Port in al oder ax ein.
Beispiel:
in al,60h ;Byte vom Tastaturpuffer in al lesen
INC
Addiert (Incrementiert) den Operanden um 1.
Beispiel:
mov ax,07h
inc ax ;ax=08h
inc Var1 ;Incrementieren einer Variablen im Speicher
!INT
Löst einen Interrupt aus. Wenn ein Interrupt über den INT Befehl ausgelöst wird
passieren zwei Dinge:
1. Das Flagregister wird auf den Stack gepusht
2. Ein FAR CALL wird ausgelöst zu der Segment:Offset Adresse die sich in der
Interruptvektor-Tabelle befindet (dort umgekehrt abgespeichert Offset:Segment).
Bei dieser Adresse befindet sich der Code des Interrupts. Die Rückkehr ins
Programm erfolgt durch einen IRET Befehl.
[CD; Speziell Int 3: CC]
Diese Tabelle besteht aus 256 Doppelwörtern und reicht von 0000:0000 bis 0000:0400h.
Die Offset-Adresse der Interruptvektoren kann man errechnen indem man die Interruptnummer
mit 4 multipliziert. Die Segmentadresse ist immer 0000h. So ist z.B. die Adresse für den
Interrupt 21h in der Tabelle an der Stelle 21h*4 = 84h also 0000:0084h.
IRET
Rückkehr aus einer Interruptroutine. CS:IP und das Statusregister (Flags) wird
vom Stack genommen.
!JMP
Unbedingter Sprung zur angegebenen Adresse bzw. Label.
JMP FAR kann auch zu Zielen springen, die nicht im eigenen Segment liegen.
Beispiel:
jmp Weiter
.
.
.
Weiter:
[EB;E9;FF;EA]
!Bedingte Sprünge:
JE/JNE/JZ/JNZ/JC/JNC/JG/JL/JLE/JGE/JNLE/JNGE sind wichtige bedingte Sprünge.
Sie werden nur ausgeführt, wenn eine bestimmte Bedingung erfüllt ist.
JE: Jump if equal. Springe wenn gleich.
Beispiel:
cmp ax,Var1 ;vergleicht die Variable Var1 und ax indem beide subtrahiert werden.
je Gleich ;Sind sie gleich gross, ist das Ergebnis 0 und das Zero Flag wird
;gesetzt. JE prüft dieses Flag und springt wenn es gesetzt also 1 ist.
JE : Jump if equal. Springe wenn gleich. [74;0F84]
JNE : Jump if not equal. Springe wenn nicht gleich. [75;0F85]
JZ : Jump if zero. Springe wenn 0. Eigentlich das Gleiche wie JE, es hat sogar den gleichen
Opcode, d.h. es wird in die gleiche Zeichenfolge übersetzt. Aber: Übersichtlicher
wenn man nicht nur eins verwendet. [74;0F84]
JNZ : Jump if not zero. Springe wenn nicht 0. [75;0F84]
JC : Jump if Carry. Springe wenn Carry Flag gesetzt. [72;0F82]
JNC : Jump if not Carry. Springe wenn Carry Flag nicht gesetzt. [73;0F83]
JG : Jump if greater. Springe wenn grösser. [7D;0F8D]
JNG : Jump if not greater. Springe wenn nicht grösser. [7E;0F8E]
JL : Jump if less. Springe wenn kleiner. [7C;0F8C]
JNL : Jump if not less. Springe wenn nicht kleiner. [7D;0F8D]
JLE : Jump if less-equal. Springe wenn kleiner oder gleich.
JGE : Jump if greater-equal. Springe wenn grösser gleich.
JNLE: Jump if not less-equal. Springe wenn nicht kleiner oder gleich.
JNGE: Jump if not grater-equal. Springe wenn nicht grösser oder gleich.
Bedingte Sprünge haben lediglich eine Reichweite von -128 bzw. +127 Bytes. Es kann
daher schnell passieren, dass ein Ziel ausserhalb der Reichweite liegt. In diesem Fall
meldet der Assembler einen Fehler der wie folgt behoben werden kann:
Wenn es so nicht geht:
Anfang:
.
. ;Über 128 Bytes Programmcode
.
cmp ax,00h
je Anfang ;Sprungziel zu weit entfernt. --> Fehler
mov bx,40h
Dann geht es so:
Anfang:
.
. ;Über 128 Bytes Programmcode
.
cmp ax,00h
jne Weiter1 ;Sprungziel zu weit entfernt. --> Fehler
jmp Anfang
Weiter1: mov bx,40h
!LEA
LEA Ziel,Quelle (Load Effective Address). LEA berechnet den Offset und speichert das Ergebnis
im Zieloperand, d.h. im angegebenen Register.
Beispiel:
lea dx,String1
mov dx,OFFSET String ;hat fast den selben Effekt, LEA ist besser.
LODS
Lädt über das DS:SI Register ein Byte in das AL Register (LODSB) oder ein Wort
in das AX Register (LODSW). Danach wird das Si Register entsprechend (Byte oder Word) um
1 oder 2 erhöht ist das Direction-Flag gesetzt wird es erniedrigt.
!LOOP
Loop springt zur angegebenen Adresse bis das CX Register null ist. Loop subtrahiert vom
CX Register 1 und überprüft CX auf null. Ist CX nicht null springt LOOP zur angegebenen
Adresse, wenn LOOP null ist wird das Programm mit dem nächsten Befehl fortgeführt.
Beispiel:
mov cx,11 ;Die Schleife wird 11 mal durchlaufen
DoLoop:
nop ;zu wiederholende Befehle hier: NOP
Loop DoLoop
LOOPE-LOOPZ
Springt zur angegebenen Adresse, wenn CX ungleich null ist und das Zero-Flag gesetzt ist.
Beispiel:
mov cx,11 ;Die Schleife wird max. 11 mal durchlaufen
DoLoop:
nop ;zu wiederholende Befehle hier: NOP
cmp ax,Var1
Loope DoLoop ;Springe wenn cx ungleich null und ax und Var1 gleich
LOOPNE-LOOPNZ
Springt zur angegebenen Adresse, wenn CX ungleich null ist und das Zero-Flag nicht gesetzt ist.
Beispiel:
mov cx,11 ;Die Schleife wird max. 11 mal durchlaufen
DoLoop:
nop ;zu wiederholende Befehle hier: NOP
cmp ax,Var1
Loope DoLoop ;Springe wenn cx ungleich null und ax und Var1 ungleich
!MOV
Der Befehl MOV Ziel,Quelle (engl. move bewegen) überträgt ein Byte oder Word vom
Quelloperanden in den Zieloperanden. Der Quelloperand selbst wird nicht verändert.
Quell und Zieloperand müssen gelich gross sein, etwas wie z.B. mov al,cx funktioniert
nicht. Auch kann man mit MOV nicht die Register CS, IP und das Flagregister nicht verändern.
Mögliche Operandenkombinationen:
mov Reg,Reg Bsp: mov cx,ax
mov Reg,Seg. Reg Bsp: mov ax,ds
mov Reg,Mem Bsp: mov cx,Variable
mov Reg,Wert Bsp: mov bx,40h
mov Seg. Reg,Reg Bsp: mov es,cx
mov Seg. Reg,Mem Bsp: mov ss,old_ss
mov Mem,Reg Bsp: mov Variable,ax
mov Mem,Seg. Reg Bsp: mov Var,es
mov Mem,Wert Bsp: mov Var2,12
Abk.: Reg=CPU Register, Seg. Reg=Segment-Register, Mem=Memory(Speicher)
MOVS
MOVSB (MOVe String, Byte) bzw. MOVSW (MOVe String, Word) überträgt ein Byte oder Word
das durch DS:SI adressiert wird nach ES:DI, MOVS stellt also eine Kombinatiom von LODS und STOS
dar. Nach jeder Übertragung werden SI und DI je nach Direction Flag erhöht (default) oder
erniedrigt (je nach Direction Flag - siehe auch STD bzw. CLD). Mit REP können mehrere Daten
kopiert werden.
Beispiel:
lea si,Quelle ; Woher kopieren ?
lea di,Ziel ; Wohin kopieren (vorher es setzen)
mov cx,Laenge ; Wieviel kopieren ?
rep movsb ; Kopieren
MUL
MUL Multipliziert den vorzeichenlosen Wert des Operanden mit dem vorzeichenlosen Wert im
Akkumulator miteinander. Man unterscheidet zwischen Byte und Word Multiplikation.
Byte Multiplikation:
Der erste Wert muss sich im AL Register befinden, der andere wird hinter MUL angegeben und muss
sich in einem 8 Bit Register oder einer Byte Speicherstelle befinden. Das Ergebnis wird in AX
abgelegt.
Beispiel:
mov bl,10
mov al,8
mul bl ;==> ax = 80
mov al,20
mov Var1,20
mul Var1 ;==> ax = 400
Word Multiplikation:
Ein Operand muss sich im AX Register befinden, der andere in einem 16 Bit Register oder einer
Word Speicherstelle. Der High-Teil des Ergebnisses wird in DX abgelegt, der Low-Teil in AX.
Beispiel:
mov ax,350
mul ax ;DX:AX = AX * AX
Weiter zu Teil 2.