MASM32-SDK (Windows Konsolapplikationen):
Plausibilieren der Eingabe und Übersetzungen von Zahlen in ASCII mittels atodw, ustr$ und printf

Bei dem letzten Beispiel auf der vorhergehenden Webseite wird darauf hingewiesen, dass das Beispiel nicht umfassend ist. Es fehlt die Überprüfung, ob die per Tastatur erfolgte Eingabe wirklich eine Zahl ist. Außerdem wird die Eingabe ohne vorhergehende Aufbereitung übernommen. Das hat zur Folge, dass Eingaben mit zusätzlichen Zeichen links, rechts oder in innerhalb der Zahl zu falschen Ergebnissen führen.

Bei dem auf dieser Webseite vorgestellten Programm wird gegen die vorstehenden Mängel etwas getan.

Die Programmlogik folgt weitgehend dem Beispiel zu .repeat, .until, .if, elseif, .else und endif aus der vorherigen Webseite. Für die Überprüfung der numerischen Eingabe wird die auf der vorherigen Webseite im Abschnitt „Byteweise Zeichenkette lesen, bearbeiten und abspeichern” beschriebene Schleifentechnik genutzt. Allerdings erfolgt keine Abspeicherung!


Plausibilieren der Eingabe und Übersetzungen von Zahlen in ASCII mittels atodw, ustr$ und printf
Eine kurze Interpretation zu diesem Programm steht unterhalb des Quellprogrammtextes.
debugFT  equ FALSE
include  c:\masm32\include\mymasm32rt.inc
.LIST
.data?
lpstring        dd ?                    ;zeigt auf den per Input eingetippten String
lpResult        dd ?                    ;zeigt auf den Ausgabestring bei ustr$
.data
eingabe         db      "Eingetippt hatten Sie "
eingabezahl     db      20 dup (" ")
crlf            db      13,10,0
eingabe1        db      "Eingetippt hatten Sie ",0

; Variablen für die Anzeige mit dem Makro printf
sint  DWORD     ?
uint  DWORD     ?
hint  DWORD     ?

.code
start:
    .repeat

        write "Bitte geben Sie eine Ganzzahl im Bereich 1 bis 200 ein.",13,10
        write "99 beendet das Programm.",13,10
        mov lpstring, input("Ihre Eingabe: ")

        mov eax, trim$(lpstring)            ;entfernt spaces und Tabulatoren vor und hinter
                                            ;der Zahl. Liefert die neue Stringlänge zurück
;Prüfen auf numerische Zeichenkette
        mov esi, lpstring       ;Adresse der Zeichenkette

@@:     mov al, [esi]           ;Byte aus String lesen
        inc     esi             ;auf nächstes Byte vorrücken
        or      al, al          ;Ende erreicht?
        je      @F              ;ja
                                ;ASCII 0..9 haben die Codes 30h...39h
        xor     al,30h          ;Gültige Codes nun 00h...09h
        cmp     al,0ah
        jb @B                   ;Passt! Weiter mit dem nächsten Byte

        write     "Bitte nur Ziffern eingeben!!!",13,10
        xor       eax,eax       ;EAX loeschen
        jmp       skip          ;und dann keine weitere Bearbeitung der
                                ;fehlerhaften Eingabe
;Ist ein Leerstring vorhanden, dann wird von invoke adodw die Eingabe der Zahl 0 unterstellt
@@:     invoke  atodw, lpstring         ;Eingabe konvertieren von String nach Integer
                                        ;Integer steht danach in eax

        push    eax                     ;sichern wegen der write-Befehle
        .if eax == 99
            write "Das Programmende wurde angefordert",13,10
        .elseif eax > 0 && eax < 201
            write "Die Zahleneingabe war O.K.",13,10
        .else
            write "So nicht!!!",13,10
        ..endif
            pop     eax

            push    eax
            invoke  dwtoa, eax, offset eingabezahl

            print   offset eingabe          ;Text und Wert
            print   offset crlf             ;Zeilenwechsel
            pop     eax
            push    eax
            mov     lpResult, ustr$(eax)
            print   offset eingabe1         ;nur Text
            print   lpResult                ;nur Wert
            print   offset crlf             ;Zeilenwechsel
            pop     eax
skip:
    .until eax == 99

;------------------
; Der folgende Programmabschnitt demonstriert Funktionen des
; Makros printf. Es handelt sich um einen angepassten Ausschnitt
; aus der Beschreibung von printf in der Hilfsdokumentation
; des MASM32-SDKs im Abschnitt
; High Level Macro Help / Console Mode Macros
;------------------

    mov sint, -1234             ; signed integer
    mov uint, 9876              ; unsigned integer
    mov hint, 1024              ; unsigned integer
    FLOAT8 fp64, 12345.67890    ; 64 bit FLOAT value

    printf("%d\t is a signed integer\n",sint);
    printf("%u\t is an unsigned integer\n",uint);
    printf("0%Xh\t is an unsigned integer in hex\n",hint);
    printf("%f\t is an unsigned float value\n",fp64);

    printf("%d (mit Vorzeichen),%u (ohne Vorzeichen),\n",sint,uint)
    printf("%Xh (hexadezimal=1024 dezimal), %f (REAL8 Gleitkommazahl)\n\n",hint,fp64)

    inkey                       ;Tastendruck abwarten bei Programmende
    invoke ExitProcess, 0

end start

Interpretation des Programmes

  • @@, @B, @F: Das Programm verwendet zwei sogenannte anonyme Labels. Sie erscheinen im Programmtext als @@. Bei den Verzweigungsbefehlen führt der Sprung nach @B auf den vorherigen anonymen Label zurück. @F führt zum darauffolgenen anoymen Label. Die Eselsbrücke lautet @B wie backward, @F wie forward.
  • mov eax, trim$(lpstring): Diese Funktion entfernt Zwischenräume und Tabulatoren vor und hinter der Zeichenkette. Außerdem gibt sie in eax die neue Stringlänge zurück. Die Beschreibung ist in der beim MASM32-SDK mitgelieferten Hilfe im Abschnitt „High Level Macros Help / Macro Categories / String Macros” zu finden.
  • @@: Die anschließende Plausibilierung auf rein numerische Eingabe einschließlich Ausgabe der diesbezüglichen Fehlermeldung steht zwischen den beiden anonymen Labels. Die zu prüfende ASCIIZ-Zeichenkette wird über das esi-Register adressiert. Die Überprüfung jedes einzelnen Zeichen erfolgt mittels der logischen XOR-Verknüpfung. Nur die 10 Ziffern von 0 bis 9 haben die ASCII-Codierung 30h bis 39h.
    Das erste ungültige Eingabezeichen bewirkt die Ausgabe des Fehlertextes und das Überspringen der weiteren Verarbeitung. Die repeat-Schleife wird durch den Sprung zum Label skip: erneut durchlaufen.
  • invoke dwtoa, eax, offset eingabezahl und
    mov lpResult, ustr$(eax): Es werden zwei verschiedene Verfahren der Umwandlung einer Integerzahl in einen ASCIIZ-String gezeigt. Die Ergebnisse aus den Umwandlungen erfordern zwei unterschiedliche Verfahren zur Aufbereitung der Bildschirmanzeige. Beide Umwandlungsverfahren sind in der beim MASM32-SDK mitgelieferten Hilfe knapp beschrieben.
  • skip: Unterhalb dieser Sprungmarke wird die Umwandlung von Zahlen mittels der Makros printf gezeigt. Die Quelle dazu und ein Hinweis, wo die Befehlsbeschreibung zu printf steht, sind im zugehörigen Kommentarblock aufgeführt.
Letztes Upload: 24.03.2023 um 11:35:14 • Impressum und Datenschutzerklärung