DOS-Funktion Zeichenkettenausgabe

AH=09: Funktionscode; Zeichenkettenausgabe, Endeerkennung: $
DS=xxxx: Segmentadresse der auszugebenden Zeichenkette
DX=yyyy: Offsetadresse der auszugebenden Zeichenkette

Programmbeispiel

Hinweis: Diese DOS-Funktion modifiziert irrtümlich das AL-Register !

Ziel: Ausgabe binärer Zahlen (Dualzahlen) als eine Kette von Nullen und Einsen

Carry-Flag: RCL-, RCR-, ADC-, SBB-, CLC-, STC- und CMC-Befehl

Carry-Flag im Statusregister; Debug: CY=Carry, NC=Non Carry

ADD AX,BX : für AX=FFFF und BX=0001 → Carry gesetzt
ADD AX,BX : für AX=0000 und BX=0001 → Carry nicht gesetzt
SUB AX,BX : für AX=0001 und BX=0001 → Carry nicht gesetzt
SUB AX,BX : für AX=0000 und BX=0001 → Carry gesetzt

RCL Operand,1  Rotate Carry Left one bit
RCR Operand,1  Rotate Carry Right one bit

Carry-Flag BL-Register  
x 01011010 Ausgangszustand
0 1011010x nach RCL BL,1
1 011010x0 nach RCL BL,1
0 11010x01 nach RCL BL,1
1 1010x010 nach RCL BL,1
1 010x0101 nach RCL BL,1
0 10x01011 nach RCL BL,1
1 0x010110 nach RCL BL,1
0 x0101101 nach RCL BL,1

ADC Operand1,Operand2  (Add with Carry: Operand1:=Operand1+Operand2+CarryFlag)

MOV DL,0
ADC DL,30
Konsequenz: Zeichen '0' im DL-Register, falls Carry-Flag zuvor nicht gesetzt; Zeichen '1' im DL-Register, falls Carry-Flag zuvor gesetzt

SBB Operand1,Operand2  (Subtract with Borrow: Operand1:=Operand1-Operand2-CarryFlag)

CLC  Carry-Flag löschen
STC  Carry-Flag setzen
CMC  Carry-Flag negieren

LOOP-Befehl (Zählschleifen)

LOOP Offsetadresse

Erster Schritt: Dekrementiere das CX-Register um den Wert Eins
Zweiter Schritt: Springe zu der angegebenen Offsetadresse falls nach dem Dekerementieren das CX-Register einen Wert ungleich Null enthält, oder fahre mit dem unmittelbar auf den LOOP-Befehl folgenden Befehl fort falls nach dem Dekrementieren das CX-Register den Wert Null enthält

Distanzberechnung: Zieladresse (angegebene Offsetadresse) minus Folgeadresse (Offsetadresse des unmittelbar auf den LOOP-Befehl folgenden Befehl)

Beispiel zur Distanzberechnung: 0105 - 0112 = FFF3 → Eingetragene 8-Bit Sprungdistanz: F3

Ziel: Ausgabe binärer Zahlen (Dualzahlen) als Hexadezimalzahlen (d.h. in Hexziffern)
- wird erst am nächsten Vorlesungstag erreicht -

Zero-, Sign- und Overflow-Flag; CMP-Befehl; Sprungbefehle

Zero-Flag im Statusregister; Debug: ZR=Zero, NZ=Non Zero

Gesetzt bei Null als Ergebnis einer arithmetischen Operation

SUB AX,BX : für AX=BX → Zero gesetzt
SUB AX,BX : für AX≠BX → Zero nicht gesetzt

Sign-Flag im Statusregister; Debug: NG=Negativ, PL=Plus

Gesetzt bei negativer Zahl als Ergebnis einer arithmetischen Operation

SUB AX,BX : für AX=0000 und BX=0001 → Sign gesetzt
SUB BX,AX : für AX=0001 und BX=0000 → Sign nicht gesetzt

Overflow-Flag im Statusregister; Debug: OV=Overflow, NV=Non Oberflow

Gesetzt bei fehlerhafter Vorzeicheninterpretation des Ergebnis einer arithmetischen Operation

ADD AL,BL : für AL=40 und BL=50 → Overflow gesetzt

  • 4016+5016 = 9016
  • 9016 bzw. 14410 im 8-Bit Register als -7016 bzw. -11210 interpretiert
  • Einerkomplement von 10010000: 01101111, Zweierkomplement von 10010000: 01101111+1 = 01110000
  • 14410 liegt nicht im Zweierkomplementwertebereich -12810...12710
  • fehlerhafte Vorzeicheninterpretation
  • Hinweis: Bei der Addition oder Subtraktion von Werten größer als 7F (8-Bit) oder 7FFF (16-Bit) wird das Overflow-Flag grundsätzlich nicht gesetzt

    CMP Operand1,Operand2  Vergleich

    CMP AX,BX entspricht SUB AX,BX ohne Speicherung des arithmetischen Ergebnis in AX (Das arithmetische Ergebnis dient nur zum Setzen und Rücksetzen der Flags)

    Erläuterungen zu den Sprungbefehlen:

    (NG∧NV)∨(PL∧OV) = Sign-Flag ungleich Overflow-Flag
    (NG∧OV)∨(PL∧NV) = Sign-Flag gleich Overflow-Flag

    PL,NV: Kein Überlauf (Zweierkomplement richtig) → Ergebnis Subtraktion positiv (≥)
    NG,NV: Kein Überlauf (Zweierkomplement richtig) → Ergebnis Subtraktion negativ (<)
    PL,OV: Überlauf (Zweierkomplement falsch) → eigentlich: NG,NV (<)
    NG,OV: Überlauf (Zweierkomplement falsch) → eigentlich: PL,NV (≥)

    Sprungweite bedingter Sprungbefehle: theoretisch -128..127 Bytes, effektiv -126..129 Bytes
    Sprungweite unbedingter Sprungbefehl: 64 KB (gesamtes Segment)

    0200 JE 0300
    0202 ...
    falsch !

    0200 JNE 0205
    0202 JMP 0300
    0205 ...
    richtig !

    Exkurs: Vorzeichenbehaftete Multiplikation und Division

    IMUL Operand  (vergleiche vorzeichenlose Multiplikation mit dem MUL-Befehl)

    IDIV Operand  (vergleiche vorzeichenlose Division mit dem DIV-Befehl)

    Exkurs: Byte-, Wort- und Doppelwortkonvertierungen

    CBW  AX := AL (inklusive Vorzeichenerweiterung)

    CWD  DX:AX := AX (inklusive Vorzeichenerweiterung)