Testlauf Version 1 (fwrite, Zeileneingabe mit privatem StdIncr statt StdIn)Nacheinander wird aufgerufen:
C:\masm32\Uebung\Konsole>linein1 aaa.txt Eingabe mehrere Zeilen. Eingabeende mit Ctrl Z ab der zweiten Eingabestelle einer Zeile >Alle meine Entlein schwimmem auf dem See, >Köpfchen in das Wasser, Beichen in die Höh' > >Das war es!^Zna noch länger? Press any key to continue ... C:\masm32\Uebung\Konsole>dir aaa.txt Datenträger in Laufwerk C: ist LW_C Volumeseriennummer: F26A-A8AA Verzeichnis von C:\masm32\Uebung\Konsole 30.01.2019 20:51 144 aaa.txt 1 Datei(en), 144 Bytes 0 Verzeichnis(se), 46.168.203.264 Bytes frei C:\masm32\Uebung\Konsole>hd aaa.txt 00000000: 41 6C 6C 65 20 6D 65 69 6E 65 20 45 6E 74 6C 65 | Alle meine Entle 00000010: 69 6E 20 73 63 68 77 69 6D 6D 65 6D 20 61 75 66 | in schwimmem auf 00000020: 20 64 65 6D 20 53 65 65 2C 0D 0A 4B 94 70 66 63 | dem See,..Köpfc 00000030: 68 65 6E 20 69 6E 20 64 61 73 20 57 61 73 73 65 | hen in das Wasse 00000040: 72 2C 20 42 65 69 63 68 65 6E 20 69 6E 20 64 69 | r, Beichen in di 00000050: 65 20 48 94 68 27 0D 0A 0D 0A 70 66 63 68 65 6E | e Höh'....pfchen 00000060: 20 69 6E 20 64 61 73 20 57 61 73 73 65 72 2C 20 | in das Wasser, 00000070: 42 65 69 63 68 65 6E 20 69 6E 20 64 69 65 20 48 | Beichen in die H 00000080: 94 68 27 0D 0A 44 61 73 20 77 61 72 20 65 73 21 | öh'..Das war es! 00000090: | ................ C:\masm32\Uebung\Konsole>linein1 /? lineout Testprogramm Konsoleingabe mit Abspeicherung in Datei Aufruf: [/?|dateiname] Wenn kein Dateiname angegeben ist, erfolgt die Speicherung in c:/temp/versuch.txt Das Programm nimmt mehrzeilige Texteingaben entgegen und speichert sie in einer Datei Press any key to continue ... |
Quellprogramm Version 1 (fwrite, Zeileneingabe mit privatem StdIncr statt StdIn)Eine Interpretation steht unterhalb des Quellprogrammtextes.comment * --------------------------- Teile der Dateizugriffe nach masm32/examples\exampl07/ppfileio.asm Build as a CONSOLE mode application Testprogramm fuer fprint, Zeileneingabe mit privatem StdIncr statt StdIn Es werden mehrere Zeilen uber die Konsole eingetippt und in die gewuenschte beim Programmaufruf angegebene Datei gespeichert Falls keine Datei angegeben wurde, erfolgt die Speicherung nach c:\temp\versuch.txt mymasm32rt.inc - siehe fredriks.de/8086asm/masm321.php?f=2#mymasm32rt ----------------------------------------------- * debugFT equ FALSE include c:\masm32\include\mymasm32rt.inc Main PROTO ;erforderlich weil Main eine Prozedur ist .LIST ; ------------ ; Locales Makro ; ------------ ; StdIncr ermoeglicht die Konsoleingabe ohne Abschneiden von CR LF am ; Ende der Eingabezeile. ; Es ist eine Umformung aus masm32/m32lib/stdin.asm ; ;StdIncr erfordert in Main PROC: ; LOCAL hInput :DWORD ; LOCAL bRead :DWORD ; ------------ StdIncr MACRO buffer,lenbuffer invoke GetStdHandle,STD_INPUT_HANDLE mov hInput, eax invoke SetConsoleMode,hInput,ENABLE_LINE_INPUT or \ ENABLE_ECHO_INPUT or \ ENABLE_PROCESSED_INPUT invoke ReadFile,hInput,ADDR buffer,lenbuffer,ADDR bRead,NULL ENDM ; ------------ .data lpos dword 0 ;Stringlaenge im Low-byte, Position von ctrlZ im High-byte von cx savech db 0 ;sichert ob ctrlZ buffer1 db 0 ;spaeter: switch Teil / oder Datenpuffer buffer1p1 db 511 dup(0) ;spaeter: Switch Teil ? oder Fortsetzung Datenpuffer lpbuffer1 equ $ - buffer1 buffer2 db 260 dup(0) ;buffer2 fuer Dateiname lpbuffer2 equ $ - buffer2 ;Defaultwerte fname db 'C:\temp\versuch.txt',0 lfname equ $ - fname hilfe db "lineout Testprogramm Konsoleingabe mit Abspeicherung in Datei",cr,lf db "Aufruf: [/?|dateiname]",cr,lf db "Wenn kein Dateiname angegeben ist, erfolgt die Speicherung in c:/temp/versuch.txt",cr,lf db "Das Programm nimmt mehrzeilige Texteingaben entgegen und speichert sie in",cr,lf db "einer Datei",cr,lf crlf db cr,lf,0 ;Zeilenwechsel ;ergaenzt hilfe msg1 db "Eingabe mehrere Zeilen. Eingabeende mit Ctrl Z ab der " db "zweiten Eingabestelle einer Zeile",cr,lf,0 msg2 db 62,0 .code start: invoke Main inkey invoke ExitProcess,eax ;------------------------------- Main PROC LOCAL hFile :DWORD ;file handle LOCAL bwrt :DWORD ;variable for bytes written LOCAL cloc :DWORD ;current location variable LOCAL txt :DWORD ;text handle LOCAL flen :DWORD ;file length variable LOCAL hMem :DWORD ;allocated memory handle LOCAL hInput :DWORD ;fuer die Umgehung von StdIn LOCAL bRead :DWORD invoke GetCL,1,ADDR buffer1 ;Parameter abfragen cmp eax, TRUE je @F invoke MemCopy,ADDR fname,ADDR buffer2,lfname jmp param99 ;kein Parameter angegeben ;1. Parameter: Switch oder Dateiname? @@: mov byte ptr al,buffer1 cmp al,'/' jne @F ;O.K., Dateiname in buffer1 mov byte ptr al,buffer1p1 cmp al,'?' jne @F ;Dateiname call help ;/? in buffer1. Also Hilfstextanzege ret @@: mov flen, len(ADDR buffer1) ;Dateiname laut Parameter nach buffer2 invoke MemCopy,ADDR buffer1,ADDR buffer2,flen param99: DumpMem offset lpos, 32, "lpos + buffer1" DumpMem offset buffer2, 32, "lpos + buffer2" .if rv(exist,ADDR buffer2) != 0 ;if file already exists test fdelete(ADDR buffer2), eax ;delete it .endif ; ---------------------------------- ; create the file ; ---------------------------------- mov hFile, fcreate(ADDR buffer2) ;create the file invoke StdOut,ADDR msg1 ;Anzeige Bedienungsanleitung konsoleingabe: invoke StdOut,ADDR msg2 ;Anzeige Prompt StdIncr buffer1,lpbuffer1 ;lesen Eingabezeile DumpMem offset lpos, 32, "pos + buffer1 nach Taste" mov edi,offset buffer1 lenstr: xor ecx,ecx ;laenge und ggf. position von ctrlZ des ; ueber edi adressierten strings nach ecx @@: mov al,[edi] or al,al jz @F ;ende gefunden inc cl ;Laenge +1 inc edi cmp al,ctrlZ ;Eingabeende angefordert? jne @B dec cl mov ch,cl ;Position von ctrlZ dec edi xor al,al mov byte ptr [edi],al ;Neues Stringende an Position von ctrlZ und fertig! DumpMem offset lpos, 32, "pos + buffer1 nach Taste lenstr" @@: mov savech,ch ;sichert ob ctrlZ xor ch,ch mov lpos,ecx ;Stringlaenge nun in lpos DumpMem offset lpos, 32, "pos + buffer1 nach Taste lenstr" mov bwrt, fwrite(hFile,ADDR buffer1,lpos) ;write data to file mov ah,savech or ah,ah ;fertig, wenn ah <> 0 jz konsoleingabe fclose hFile ;Datei schliessen mov eax,TRUE ret Main ENDP ; ----- ; Unterprogramm Hilfstext ausgeben ; ----- help PROC print offset hilfe mov eax,99 ;Errorlevel 99 und Schluss! ret help ENDP end start |
Interpretation Quellprogramm Version 1 (fwrite, Zeileneingabe mit privatem StdIncr statt StdIn)Gleich am Anfang der Programmes wird in einem Kommentar auf masm32/examples\exampl07/ppfileio.asm hingewiesen. Einige der darin enthaltenen Kommentartexte sind ohne Übersetzung in das Quellprogramm eingeflossen.DBGWIN_DEBUG_ON = 1: Diese und die folgende Zeile bewirken, dass die im weiteren Programmtext enthaltenen Speicherauszüge mittels Debuggingwerkzeug DumpMem assembliert oder ignoriert werden. StdIncr MACRO buffer,lenbuffer: Dies ist die neue Definition des Makros zum Einlesen einer auf der Tastatur eingetippten Zeile und Speichern in den angegebenen Puffer (1.Parameter) mit Längenbegrenzung. Das Makro ist eine verkürzte Version von masm32\m32lib\stdin.asm. Anders als stdin.asm schneidet dies Makro nicht Zeilenende nicht ab. Das Zeilenende wird durch die beiden Bytes CR (Carriage return/Wagenrücklauf) und LF (Linefeed/Zeilenvorschub) gekennzeichnet. Main PROC: Der Ablauf der Prozedur Main beginnt nach einer Vielzahl von Definition lokaler Variablen und Konstanten bei der Kommentarzeile 1. Parameter: Switch oder Dateiname? Bis zur Sprungmarke param99 erfolgt die Auswertung der beiden optionalen Programmaufrufparameter. Falls /? angegeben wurde, erfolgt die Ausgabe der Bedienungsanleitung und das Programm wird ohne weitere Aktion beendet. Wurde ein Dateiname beim Programmaufruf angegeben, wird er nach buffer2 übernommen. Wurde kein Dateiname angegeben, wird der im Feld fname definierte Defaultdateiname nach buffer2 übernommen. Hinter param99 erfolgt
Innerhalb der Eingabeschleife wird die Länge der eingegebenen Zeile ins Datenfeld lpos eingestellt. Falls Dateiende anfordert wurde (ctrl Z), wird dessen Position in savech gesichert. Somit ist es möglich, durch die drei Programmzeilen mov ah,savech or ah,ah ;fertig, wenn ah <> 0 jz konsoleingabefestzustellen, ob das Programm beendet werden soll. |
Zum Quellprogramm Version 2 (fprint, Zeileneingabe mit StdIn)Die Veränderungen im Vergleich zu Version 1 sind:
comment * --------------------------- Teile der Dateizugriffe nach masm32/examples\exampl07/ppfileio.asm Build as a CONSOLE mode application Testprogramm fuer fprint, Zeileneingabe mit StdIn Es werden mehrere Zeilen uber die Konsole eingetippt und in die gewuenschte beim Programmaufruf angegebene Datei gespeichert Falls keine Datei angegeben wurde, erfolgt die Speicherung nach c:\temp\versuch.txt mymasm32rt.inc - siehe fredriks.de/8086asm/masm321.php?f=2#mymasm32rt ----------------------------------------------- * debugFT equ FALSE include c:\masm32\include\mymasm32rt.inc Main PROTO ;erforderlich weil Main eine Prozedur ist .LIST .data lpos dword 0 ;Stringlaenge im Low-byte, Position von ctrlZ im High-byte von cx savech db 0 ;sichert ob ctrlZ buffer1 db 0 ;spaeter: switch Teil / oder Datenpuffer buffer1p1 db 511 dup(0) ;spaeter: Switch Teil ? oder Fortsetzung Datenpuffer lpbuffer1 equ $ - buffer1 buffer2 db 260 dup(0) ;buffer2 fuer Dateiname lpbuffer2 equ $ - buffer2 ;Defaultwerte fname db 'C:\temp\versuch.txt',0 lfname equ $ - fname hilfe db "lineout Testprogramm Konsoleingabe mit Abspeicherung in Datei",cr,lf db "Aufruf: [/?|dateiname]",cr,lf db "Wenn kein Dateiname angegeben ist, erfolgt die Speicherung in c:/temp/versuch.txt",cr,lf db "Das Programm nimmt mehrzeilige Texteingaben entgegen und speichert sie in",cr,lf db "einer Datei",cr,lf crlf db cr,lf,0 ;Zeilenwechsel ;ergaenzt hilfe msg1 db "Eingabe mehrere Zeilen. Eingabeende mit Ctrl Z ab der " db "zweiten Eingabestelle einer Zeile",cr,lf,0 msg2 db 62,0 .code start: invoke Main inkey invoke ExitProcess,eax ;------------------------------- Main PROC LOCAL hFile :DWORD ;file handle LOCAL bwrt :DWORD ;variable for bytes written LOCAL cloc :DWORD ;current location variable LOCAL txt :DWORD ;text handle LOCAL flen :DWORD ;file length variable LOCAL hMem :DWORD ;allocated memory handle LOCAL hInput :DWORD ;fuer die Umgehung von StdIn LOCAL bRead :DWORD invoke GetCL,1,ADDR buffer1 ;Parameter abfragen cmp eax, TRUE je @F invoke MemCopy,ADDR fname,ADDR buffer2,lfname jmp param99 ;kein Parameter angegeben ;1. Parameter: Switch oder Dateiname? @@: mov byte ptr al,buffer1 cmp al,'/' jne @F ;O.K., Dateiname in buffer1 mov byte ptr al,buffer1p1 cmp al,'?' jne @F ;Dateiname call help ;/? in buffer1. Also Hilfstextanzege ret @@: mov flen, len(ADDR buffer1) ;Dateiname laut Parameter nach buffer2 invoke MemCopy,ADDR buffer1,ADDR buffer2,flen param99: DumpMem offset lpos, 32, "lpos + buffer1" DumpMem offset buffer2, 32, "lpos + buffer2" .if rv(exist,ADDR buffer2) != 0 ;if file already exists test fdelete(ADDR buffer2), eax ;delete it .endif ; ---------------------------------- ; create the file ; ---------------------------------- mov hFile, fcreate(ADDR buffer2) ;create the file invoke StdOut,ADDR msg1 ;Anzeige Bedienungsanleitung konsoleingabe: invoke StdOut,ADDR msg2 ;Anzeige Prompt invoke StdIn,ADDR buffer1,lpbuffer1 ;lesen Eingabezeile DumpMem offset lpos, 32, "pos + buffer1 nach Taste" mov edi,offset buffer1 lenstr: xor ecx,ecx ;laenge und ggf. position von ctrlZ des ; ueber edi adressierten strings nach ecx @@: mov al,[edi] or al,al jz @F ;ende gefunden inc cl ;Laenge +1 inc edi cmp al,ctrlZ ;Eingabeende angefordert? jne @B dec cl mov ch,cl ;Position von ctrlZ dec edi xor al,al mov byte ptr [edi],al ;Neues Stringende an Position von ctrlZ und fertig! DumpMem offset lpos, 32, "pos + buffer1 nach Taste lenstr" @@: mov savech,ch ;sichert ob ctrlZ xor ch,ch mov lpos,ecx ;Stringlaenge nun in lpos DumpMem offset lpos, 32, "pos + buffer1 nach Taste lenstr" fprint hFile,offset buffer1 ;write line to file mov ah,savech or ah,ah ;fertig, wenn ah <> 0 jz konsoleingabe fclose hFile ;Datei schliessen mov eax,TRUE ret Main ENDP ; ----- ; Unterprogramm Hilfstext ausgeben ; ----- help PROC print offset hilfe mov eax,99 ;Errorlevel 99 und Schluss! ret help ENDP end start |