MASM32-SDK (Windows Konsolapplikationen):
Tastatureingabe per Input-Befehl, etwas Fehlersuche mit VKDebug sowie Ein- und Ausgabeumleitung

Zum Umgehen des auf dieser Seite beschriebene Problems mit der Umlautdarstellung siehe Probleme mit nicht nur deutschen Umlauten zwischen Windows und MSDOS
Der MASM32-SDK wird mit einer Testhilfe ausgeliefert. Die Bedienungsanleitung dazu ist in der mitgelieferten Hilfe unter dem Punkt „VKDebug help” zu finden. Insgesamt stellt VKDebug 16 Werkzeuge zur Fehlersuche bereit. Einige Beispiele sind unter \masm32\vkdebug\example zu finden.

In dem auf dieser Webseite beschrieben Übungsprogramm wird das Debuggingwerkzeug „DumpMem” genutzt. Dessen Anzeigen erscheinen in einem Extrafenster.

Der Programmablauf demonstriert zuerst drei Möglichkeiten, eine Textanzeige im Konsolbildschirm zu erzeugen. Gemeinsam ist ihnen, dass der erste Buchstabe des Wortes „Übungsprogramm” verkehrt angezeigt wird.

Anschließend wird ein Text mit einem Umlaut und dem Buchstaben „ß” eingetippt. Diesmal wird jedoch der Text sowohl auf dem Konsolbildschirm als auch in der Messagebox korrekt dargestellt:

Ablauf des Übungsprogrammes zur Konsoleingabe
Zwischen der Textausgabe „Jeder Grizzlybär ist groß” auf dem Konsolbildschirm (schwarzer Hintergrund) und der Messagebox wurde das Unterprogramm towin aufgerufen. Es konvertiert die Zeichencodierung der deutschen Zeichen ä, ö, ü, Ä, Ö, Ü und ß von Konsoldarstellung auf Windowsdarstellung. Das Konvertierverfahren ist beim Filterprogramm UML beschrieben.

Im „Debug Window for MASM32” werden die ersten 32 Bytes ab dem Merkmal lpString im .data-Bereich dargestellt. In den beiden Dumps vor und nach call towin stellen die 14 Bytes ab Adresse 043068 die Codewandeltabelle dar.

Aus Testgründen sind im .data-Bereich die beiden Bytes testbyte und testbyte1 vorhanden. In den beiden Dumps findet man sie auf den Adressen 403076 und 403077 wieder. 4A und 65 sind die ASCII-Codierungen der Buchstaben „Je”. Sie kommen von der Tastatureingabe.



Das Konsoleingabetestprogramm
Eine kurze Interpretation zu diesem Programm steht unterhalb des Quellprogrammtextes.
.586                                    ; create 32 bit code
.model flat, stdcall                    ; 32 bit memory model
option casemap :none                    ; case sensitive

.XLIST
    include \masm32\include\windows.inc     ; always first
    include \masm32\macros\macros.asm       ; MASM support macros

; include files that have MASM format prototypes for function calls
; -----------------------------------------------------------------
    include \masm32\include\masm32.inc
;   include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
;   include c:\masm32\include\shell32.inc
    include c:\masm32\include\msvcrt.inc
    include \masm32\include\debug.inc           ;fuer debug

; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ------------------------------------------------
    includelib \masm32\lib\masm32.lib
;   includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
;   includelib c:\masm32\lib\shell32.lib
    includelib c:\masm32\lib\msvcrt.lib
    includelib \masm32\lib\debug.lib            ;fuer debug
.LIST
DBGWIN_DEBUG_ON = 1 ;turn it off if you don't want to include debug info into the program
DBGWIN_EXT_INFO = 1 ;turn it off if you don't want to include extra debug info into the program

.data
consoleOutHandle dd ?                           ;fraglich
consoleInHandle  dd ?                           ;fraglich
MsgBoxCaption  db "Übungsprogramm zur Konsoleingabe"
crlf           db 13,10,0
MsgBoxText     db "damit kann auch Teddy mit",13,10,"Win32 Assembler programmieren",0
LMsgBoxText    equ $-MsgBoxText-1       ;Laenge ohne die nachlaufende 0
lpstring       dd ?                     ;zeigt auf den per Input eingetippten String
comment #
Umlauttabelle, enthält Windows- und MS-Dosumlaute äöüßÄÖÜ jeweils nebeneinander
zuerst Windows, dann MS-DOS
          ä  ö  ü  Ä  Ö  Ü  ß
Windows:  e4 f6 fc c4 d6 dc df
MS-DOS:   84 94 81 8e 99 9a e1
#
umlaute db 0e4h,84h,0f6h,94h,0fch,81h,0c4h,08eh,0d6h,99h,0dch,9ah,0dfh,0e1h

testbyte  db  255                     ;fuer debug
testbyte1 db  255                     ;fuer debug

.code
start:  print offset MsgBoxCaption
        invoke StdOut, offset MsgBoxCaption
        write "Übungsprogramm zur Konsoleingabe",13,10

        DumpMem offset consoleOutHandle, 16, "Handlespeicher vor der Initialisierung"
        INVOKE GetStdHandle, STD_INPUT_HANDLE   ;fraglich
        mov consoleInHandle, eax

        INVOKE GetStdHandle, STD_OUTPUT_HANDLE  ;fraglich
        mov consoleOutHandle, eax
        DumpMem offset consoleOutHandle, 16, "Handlespeicher nach der Initialisierung"

        mov lpstring, input("Bitte hier Ihre ihre erste Eingabe: ")
        mov     ebx, lpstring
        mov     byte ptr al,[ebx]       ;1. Eingabezeichen
        mov     testbyte,al
        inc     ebx
        mov     byte ptr al,[ebx]       ;2. Eingabezeichen oder 0
        mov     testbyte1,al
        DumpMem offset lpstring, 32, "testbyte und testbyte1 vor call towin"
        dec     ebx

        print   lpstring        ;Eingabezeile zum Bildschirm
        print   offset crlf     ;Zeilenwechsel ergänzen

        call    towin           ;deutsche Umlaute in Windowscode wandeln

        DumpMem offset lpstring, 32, "lpstring nach call towin"

        invoke MessageBox, consoleOutHandle, lpstring, addr MsgBoxCaption, 35

        inkey                   ; Tastendruck abwarten bei Programmende
 invoke ExitProcess, 0

;-----
;Unterprogramme
;-----
;Unterprogramm Codewandlung Umlaut von DOS (ASCII)- in Windowscodierung
;bei einem mit 0 abgeschlossenen String
;Der zu untersuchende String wird mit ebx adressiert
;Die Tabelle Umlaute wird mit edx adressiert
;-----
towin:
        mov     edx, offset umlaute+1  ;zur Adressierung

towin1: mov     ecx,7         ;Tabelle umlaute ist 14 Zeichen lang
towin2: mov     byte ptr al,[ebx]
        or	    al,al         ;0 kennzeichnet Stringende
        jnz     towin3
        ret			      ;Konvertierung beendet bei Stringende
towin3: cmp     byte ptr al,[edx]
        je      towin9
        inc     edx           ;adressieren naechsten Tabellenplatz
        inc     edx
        loop    towin3

towin8: inc	ebx		;nächstes Zeichen adressieren
	jmp     towin

towin9: dec     edx		;wenn Umlaut, dann Zeichen ersetzen
        mov     byte ptr al,[edx]
        mov     byte ptr [ebx],al
        inc	ebx		;nächstes Zeichen adressieren
	jmp     towin

end start

Interpretation des Konsoleingabetestprogramms für MASM32
Damit bei den Labelnamen zwischen Groß- und Kleinschreibung unterschieden wird, muss die option casemap:none eingetragen sein.


Das bereinigte Konsoleingabetestprogramm
Abschließend sei das von unnötigen Dingen bereinigte Programm aufgeführt. Unterhalb des Quellprogramms steht ein Hinweis zur Ein- und Ausgabeumleitung.
.586                                    ; create 32 bit code
.model flat, stdcall                    ; 32 bit memory model
    option casemap :none                ; case sensitive

.XLIST
    include \masm32\include\windows.inc     ; always first
    include \masm32\macros\macros.asm       ; MASM support macros

; include files that have MASM format prototypes for function calls
; -----------------------------------------------------------------
    include \masm32\include\masm32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include c:\masm32\include\msvcrt.inc
    include \masm32\include\debug.inc           ;fuer debug

; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ------------------------------------------------
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib c:\masm32\lib\msvcrt.lib
    includelib \masm32\lib\debug.lib            ;fuer debug
.LIST


.data
MsgBoxCaption  db "Übungsprogramm zur Konsoleingabe"
crlf           db 13,10,0
lpstring       dd ?                     ;zeigt auf den per Input eingetippten String
comment #
Umlauttabelle, enthält Windows- und MS-Dosumlaute äöüßÄÖÜ jeweils nebeneinander
zuerst Windows, dann MS-DOS
          ä  ö  ü  Ä  Ö  Ü  ß
Windows:  e4 f6 fc c4 d6 dc df
MS-DOS:   84 94 81 8e 99 9a e1
#
umlaute db 0e4h,84h,0f6h,94h,0fch,81h,0c4h,08eh,0d6h,99h,0dch,9ah,0dfh,0e1h

.code
start:  print   offset MsgBoxCaption
        invoke  StdOut, offset MsgBoxCaption
        write   "Übungsprogramm zur Konsoleingabe",13,10

        mov     lpstring, input("Bitte hier Ihre Eingabe: ")

        print   lpstring        ;Eingabezeile zum Bildschirm
        print   offset crlf     ;Zeilenwechsel ergänzen

        mov     ebx, lpstring   ;Adresse des Eingabestrings nach ebx
        call    towin           ;deutsche Umlaute in Windowscode wandeln

        invoke MessageBox, 0, lpstring, addr MsgBoxCaption, 35

        inkey                   ; Tastendruck abwarten bei Programmende
 invoke ExitProcess, 0


;-----
;Unterprogramme
;-----
;Unterprogramm Codewandlung Umlaut von DOS (ASCII)- in Windowscodierung
;bei einem mit 0 abgeschlossenen String
;Der zu untersuchende String wird mit ebx adressiert
;Die Tabelle Umlaute wird mit edx adressiert
;-----
towin:
        mov     edx, offset umlaute+1  ;zur Adressierung

towin1: mov     ecx,7         ;Tabelle umlaute ist 14 Zeichen lang
towin2: mov     byte ptr al,[ebx]
        or	al,al         ;0 kennzeichnet Stringende
        jnz     towin3
        ret			      ;Konvertierung beendet bei Stringende
towin3: cmp     byte ptr al,[edx]
        je      towin9
        inc     edx           ;adressieren naechsten Tabellenplatz
        inc     edx
        loop    towin3

towin8: inc	ebx		;nächstes Zeichen adressieren
	jmp     towin

towin9: dec     edx		;wenn Umlaut, dann Zeichen ersetzen
        mov     byte ptr al,[edx]
        mov     byte ptr [ebx],al
        inc	ebx		;nächstes Zeichen adressieren
	jmp     towin

end start


Das bereinigte Konsoleingabetestprogramm kann mit Ein- und Ausgabeumleitungen umgehen
Wir erstellen eine einzeilige Textdatei mit dem Namen text.txt und dem Inhalt
Alle meine Entlein schwimmen auf dem See
Wenn das ausführbare bereinigte Konsoltestprogramm den Namen konsolinput.exe erhalten hätte, gäben wir im Konsolmodus - also unter CMD - ein (passende Pfade vorausgesetzt):
konsolinput <test.txt
Das Programm verhält sich so, als ob wir die erste Zeile des bekannten Kinderliedes in die Tastatur eingetippt hätten. Allerdings wird die Eingabe aus der Datei nicht auf dem Bildschirm angezeigt. Aber wir geben sie ja anschließend mit print lpstring und einem zusätzlichen Zeilenvorschub auf dem Konsolbildschirm aus.

Hätten wir

konsolinput <test.txt >test1.txt
eingetippt, so stünde in der neu erstellten Datei haargenau das, was bei dem vorhergehenden Testlauf auf dem Konsolbildschirm ausgegeben wurde.
C:\masm32\Uebung>type test1.txt
▄bungsprogramm zur Konsoleingabe
▄bungsprogramm zur Konsoleingabe
▄bungsprogramm zur Konsoleingabe
Bitte hier Ihre Eingabe: Alle meine Entlein schwimmen auf dem See
Press any key to continue ...
Letztes Upload: 24.03.2023 um 11:35:11 • Impressum und Datenschutzerklärung