8086 Assembler (MS-DOS), Programmbeispiel:
Frage-Programm

Hinweis: Das auf dieser Seite für MS-DOS beschriebene 16-bit-Programm lässt sich ab Windows 7 nicht mehr verwenden. Ein praktisch funktionsgleiches 32-bit-Programm ist im Abschnitt über den MASM32-SDK beschrieben. Das 32-bit-Programm ist auch in Windows-Versionen ab Windows 7 verwendbar.
Usage: FRAGE "prompt"[,key-list]

„FRAGE” zeigt den Prompt und wartet auf eine Eingabetaste aus der „key-list”. Der zurückgegebene Errorlevel zeigt an, die wievielte Taste der „key-list” betätigt wurde. Mit dem weiter unten dargestellten Beispiel einer .bat-Datei lässt sich erproben, dass die gültigen Antworten "j" oder "n" lauten. "J" oder "N" sind ungültig!.

Ruft man das „FRAGE” ohne „key-list” auf, so wird lediglich der Prompt-Text angezeigt. Die Gänsefüßchen um den Prompt-Text sind erforderlich, falls der Prompt-Text mindestens ein Komma enthält

Ruft man „FRAGE” ohne einen Parameter aus, wird eine Hilfsanzeige gebracht.

Das Programm hat einen kleinen logischen Fehler im Bereich um „antw6:”: Die Wandlung des eingegebenen Zeichens in Großschrift ist unnütz: Im Bereich „byte ptr[is]” steht das Zeichen unverändert so, wie es in der „key-list” mitgegeben wurde!

Das Quellprogramm ist für die Übersetzung mit dem ML 6.11d-Assembler bestimmt.

Beispiel (als .bat-Datei auszuführen):

Frage "Bitte 'J' zur Antwort Ja",nj
if errorlevel 2 goto ja
if errorlevel 1 goto nein
:ja
echo Die Antwort war "Ja"
goto raus
:nein
echo Die Antwort war "Nein"
:raus

Dies Programm ist ein schönes Programmbeispiel. Einen operativen Nutzen hat das Programm eher nicht mehr. Unter neueren Windows-Versionen wird das Programm CHOICE.EXE mit einer ähnlichen — aber erweiterten — Funktionalität ausgeliefert. Allerdings ist CHOICE.EXE unter VISTA 30720 Bytes groß. FRAGE.COM nimmt sich mit 216 Bytes dagegen geradezu winzig ist. Verwendet man den alternativen Befehlsprozessor 4DOS, so bietet sich dessen internes Kommando INKEY an.
.MODEL TINY
        page    65,132
        .286c
;FRAGE, wie ASK aus den NORTON UTILITIES, nur kuerzer
;Matthaei, 16.6.90
print_chr macro char    ;;1 Zeichen zum
        mov     dl,char ;;Bildschirm
        mov     ah,2
        int     dos
        endm

jmps    macro   to      ;kurzer Sprung
        jmp     short to
        endm

cr      equ     0dh
lf      equ     0ah

dos         equ 21h
lparm   equ     0080h   ;Parameterlaenge
fcb     equ     5ch     ;FCB aus Parameter

.CODE

        org     100h
_start: jmp     start1
;=====================
;Unterprogrammsammlung
;=====================
;PRINT MESSAGE FOLLOWING CALL PRMSG AND ENDING WITH 0
PRMSG:  mov     word ptr PRMSG2,di
        POP     di
;PRINT MESSAGE ADRESSED BY di, ENDING WITH 0
;cr wird als cr lf ausgegeben
PSTR:   mov     dl,[di]
        INC     di
        cmp     dl,0
        jz      pstr99       ;FALLS FERTIG
        cmp     dl,cr
        jnz     prstr2
        call    print_crlf
        jmp     short PSTR
prstr2: mov     ah,02
        int     21h
        jmp     short PSTR

pstr99: PUSH    di      ;Returnadresse

        mov     di,0    ;mod
PRMSG2  EQU     $-2
        RET

prstr   MACRO   TEXT    ;;PRINT STRING
        CALL    PRMSG
        DB      TEXT,0
        ENDM

;===================================
print_crlf:
        push    ax    ;Ausgabe cr lf
        print_chr cr
        print_chr lf
        pop     ax
        ret
;===================================

start1: mov     si,lparm        ;Laenge des Parameters
        xor     ch,ch
        mov     cl,[si]
        cmp     cx,0
        je      hilfe     ;Ausstieg, wenn keine Parameterangabe
start2: inc     si        ;ueberlesen fuehrende Spaces
        cmp     byte ptr[si],' '
        jne     start3
        loop    start2


;Hilfstextanzeige wenn Aufruf ohne Parameter oder nur Spaces als Parameter
hilfe:  prstr   <'FRAGE prompt[,key-list]'>
        jmp     ret1

;Ausgabe des Prompts
;Die Ausgabe endet beim Komma im Parameter, es sei denn, das Komma steht
;nach einer ungeraden Anzahl Gaensefuesschen
m_gsf   db      0

start3: mov     m_gsf,0         ;setzen Anzahl Gaensefuesschen auf gerade
        dec     si

start5: inc     si
        mov     al,[si]

        cmp     al,'"'          ;umsetzen ?
        je      start9
        cmp     al,','
        jne     start10         ;Ausgabe
        cmp     m_gsf,0
        jne     start10         ;Ausgabe wegen Merker Schluss-Komma

        jmps    antw1

start9: xor     byte ptr m_gsf,1        ;Merker Schluss-Komma umsetzen
        jmps    start99

start10: print_chr al                   ;Zeichen ausgeben
        jmps    start99

start99: loop   start5

;diverse Programmbeendigungen
ret0:   xor     al,al
        jmps    raus

ret1:   mov     al,1

;Programmende
raus:   call    print_crlf
        mov     ah,4ch
        int     dos

antw1:  dec     cx
        jz      antw3           ;Programmende, wenn hier abgearbeitet
antw2:  inc     si              ;ueberlesen fuehrende Spaces
        cmp     byte ptr[si],' '
        jne     antw4
        loop    antw2

antw3:  jmp     ret0            ;Programmende, wenn hier abgearbeitet

antw4:  push    si              ;fuer Wiederholungen
        push    cx
        mov     bl,1
antw5:  print_chr '>'
        mov     ah,0    ;Zeicheneingabe
        int     16h     ;per Tastatur

antw6:  cmp     al,cr
        je      antw5   ;cr wird ignoriert
        mov     ah,al
        and     ah,5fh  ;ah enth. das Zeichen in Grossschrift
        cmp     byte ptr[si],al
        je      antw9
        cmp     byte ptr[si],ah
        je      antw9
        inc     si
        inc     bl
        loop    antw6

        pop     cx      ;war nicht dabei - neue Eingabe anfordern!
        pop     si
        jmps    antw4

antw9:  mov     al,bl   ;Errorlevel
        jmp     raus

        end     _start
Letztes Upload: 24.03.2023 um 11:35:12 • Impressum und Datenschutzerklärung