Home

Die Messagebox MSGbox
in Visual BASIC 2010
und im Masm32 SDK

Abfragen (IF, SWITCH), Schleifen (REPEAT, LOOP)
und einige Hinweise aus der
beim MASM32 SDK mitgelieferten Hilfe

MASM32-
Infoseite

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

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:

Bild: Ablauf des Übungsprogrammes zur Konsoleingabe
Zwischen der Textausgabe „Jeder Grizlybä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  i 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 Testgü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.
  • DBGWIN_DEBUG_ON = 1 und DBGWIN_EXT_INFO = 1: Wenn statt 1 eine 0 eingetragen wird, werden die Debuggingteile nicht assembliert und nicht verlinkt. Die Größe der ausführbaren .exe-Datei reduziert sich dadurch von 4096 auf 3072 Bytes.
  • .data: Im Datenbereich sind noch einige Reste von dem Programm auf der  i vorhergehenden Webseite enthalten. Der String MsgBoxCaption db "Übungsprogramm zur Konsoleingabe",13,10,0 wurde aufgeteilt, damit man ggf. den Zeilenvorschub getrennt ansprechen kann.
  • start: Die ersten drei Zeilen demonstrieren die drei Verfahren zur Stringanzeige auf dem Konsolbildschirm. Alle drei Varianten führt keinen Zeilenvorschub durch. Deshalb wurden die anzuzeigenden Zeichenketten mit 13 und 10 verlängert.
  • DumpMem offset consoleOutHandle, 16, "Handlespeicher vor der Initialisierung": Durch diesen und den nachfolgenden zweiten ähnlichen Dumpaufruf lässt sich feststellen, was als Handle eingetragen wird. Die beiden Handles belegen die ersten 8 Bytes der beiden Dumps.
  • mov lpstring, input("Bitte hier Ihre ihre erste Eingabe: "): Zeigt den angegebenen Text als Eingabeaufforderung (Prompt) an. Die Wortfolge „Ihre ihre” ist ein Versehen.
    Bei der Texteingabe bestehen Editiermöglichkeiten wie beim Kommandoprozessor CMD: Cursor verschieben mit Pfeil links und rechts, Text einfügen, Text löschen, Markieren, Kopieren in die Zwischenablage, und Einfügen aus der Zwischenablage. Durch Betätigen der Enter-Taste wird die angezeigte Eingabe übernommen. Deren Adresse wird im Zeiger lpString eingetragen.
  • print lpstring: Da lpstring eine Adresse beinhaltet, fehlt beim Printbefehl das Wort „offset”. Anschließend wird mit einem zweiten print-Befehl ein Zeilenvorschub ausgeführt.
  • call towin: Es folgt die Wandlung der Eingabe in Windows-Codierung und anschließende Anzeige in einer Message- bzw. MSGbox.
  • towin1: mov ecx,7: Da das Programm in der 32-bit-Variante ablaufen soll, muss man für die Schleifenabwicklung per loop das ecx-Register verwenden.


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 Kinderlieds 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: 30.03.2017 um 14:31:28