Beim Eröffnen einer Datei hat der MASM32-SDK die Makros fcreate und fopen vorgesehen. Beide Makros eröffnen die Datei im UPDATE-Modus. Möchte man nur schreiben oder nur lesen, ist es günstiger, statt GENERIC_READ or GENERIC_WRITE nur GENERIC_WRITE oder nur GENERIC_WRITE anzugeben.
Um die korrekte Stelle innerhalb der Direktzugriffsdatei zu treffen, wird das Makro fseek unter Berücksichtigung von Satznummer und Satzlänge genutzt. Wir verwenden die Datei, die mit dem auf der vorhergehenden Webseite beschriebenen Übungsprogramm erstellt wurde. 0001. Datensatz 0002. Datensatz … 0049. Datensatz 0050. Datensatz Gelesen wurde die Direktzugriffsdatei C:\temp\versuch.txt Press any key to continue ... In verkürzter Darstellung sieht die Anzeige wie links gezeigt aus. |
Sequenzielles Lesen der gesamten DirektzugriffsdateiHinweise zum Programmablauf stehen hinter dem Programmlisting.comment * --------------------------- Uebungsprogramm zum sequentiellen Einlesen einer Direktzugriffsdatei mit Anzeige der Datensätze auf dem Bildschirm Build as a CONSOLE mode application 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 .data satzanfang db 'xxxx' ;gesamte satzlaenge 50 bytes satzrest db '. Datensatz' db 35 dup(0) satzlaenge equ $ - satzanfang satzanzahl equ 50 ; Die folgende 0 schliesst den gelesenen Satz ab. Vorgesehen ; fuer den fall, dass der Satz keine 0 enthält db 0 ;Defaultwerte fname db 'C:\temp\versuch.txt',0 lfname equ $ - fname crlf db 13,10,0 satznr dw 1 .code start: SetConsoleCaption "Sequenzielles Lesen einer Direktzugriffsdatei" invoke Main inkey invoke ExitProcess,eax ;------------------------------- Main PROC LOCAL hFile :DWORD LOCAL rval :DWORD ;Anzahl gelesener Bytes DumpMem offset satzanfang, 32, "satzanfang vorher" ;------------ ;Datei zum Lesen oeffnen ;------------ mov hFile, rv(CreateFileA,ADDR fname,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0) mov cx,satzanzahl ;Lesen der gesamten Datei lesen: push cx ;Schleifenzaehler sichern DumpMem offset satzanfang, 51, "satzanfang 1. Lesen" mov rval, fread(hFile,ADDR satzanfang,satzlaenge) print offset satzanfang ;Satz auf Bildschirm anzeigen print offset crlf pop cx dec cx jnz lesen fclose hFile print "Gelesen wurde die Direktzugriffsdatei ",0 print offset fname print offset crlf mov eax,TRUE ret Main ENDP end start |
Interpretation des Übungsprogramms zum sequenziellen Lesen der gesamten Direktzugriffsdatei;Datei zum Lesen oeffnen: Die folgende lange Befehlszeilemov hFile, rv(CreateFileA,ADDR fname,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0) ist die Umgehung des am Anfang dieser Webseite beschriebenen Problems mit fopen. lesen: bis jnz lesen: In dieser Schleife erfolgt das Lesen aller Sätze der Datei und deren Anzeige auf dem Bildschirm. Da die Datei unmittelbar nach ihrer Eröffnung von ihrem Anfang ab gelesen wird, braucht man sich um ihren Positionszeiger zu kümmern: Er steht nach dem Öffnen der Datei auf deren Beginn und wird beim aufeinanderfolgenden Lesen immer um die gelesene Satzlänge erhöht. Die Abspeicherung des Positionszeigers nach rval ist nicht erforderlich. |
Übungsprogramm zum direktes Lesen eines Satzes einer DirektzugriffsdateiDie Programmierung und der Test dieses Übungsprogramms erwiesen sich als so einfach, dass auf den Einbau der Testhilfe DBGWIN_DEBUG verzichtet werden konnte. Tatsächlich ist das Programm eine vereinfachte Version des Programms zum Lesen der gesamten Datei. Die Schleife zum Einlesen aller Datensätze wurde entnommen und durch das Lesen eines einzigen Satzes ersetzt. Vorher musste dessen Position innerhalb der Datei ermittelt werden.C:\masm32\Uebung\Konsole>int2ascreaddirect 0032. Datensatz Gelesen wurde die Direktzugriffsdatei C:\temp\versuch.txt Press any key to continue ... |
Direktes Lesen eines Satzes einer DirektzugriffsdateiHinweise zum Programmablauf stehen hinter dem Programmlisting.comment * --------------------------- Uebungsprogramm zum direkten Lesen eines Satzes einer Direktzugriffsdatei mit Anzeige des gelesenen Datensatzes auf dem Bildschirm Build as a CONSOLE mode application 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 .data satzanfang db '0000' ;gesamte satzlaenge 50 bytes satzrest db '. Datensatz' db 35 dup(0) satzlaenge equ $ - satzanfang satzanzahl equ 50 ; Die folgende 0 schliesst den gelesenen Satz ab. Vorgesehen ; fuer den Fall, dass der Satz keine 0 enthält db 0 ;Defaultwerte fname db 'C:\temp\versuch.txt',0 lfname equ $ - fname crlf db 13,10,0 satznr dw 32 .code start: SetConsoleCaption "Sequentielles Lesen einer Direktzugriffsdatei" invoke Main inkey invoke ExitProcess,eax ;------------------------------- Main PROC LOCAL hFile :DWORD LOCAL rval :DWORD ;Anzahl gelesener Bytes LOCAL cloc :DWORD ;Position in Datei ;------------ ;Datei zum Lesen oeffnen ;------------ mov hFile, rv(CreateFileA,ADDR fname,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0) ;-------------- ; Ermittelt Zieladresse innerhalb der Direktzugriffsdatei ; dateianfang + (satznr - 1) * satzlaenge ;-------------- xor eax,eax mov ax,satznr ;satznr dec ax mov bl,satzlaenge mul bl ;abstand ab anfang datei nun in eax mov cloc, fseek(hFile,eax,FILE_BEGIN) mov rval, fread(hFile,ADDR satzanfang,satzlaenge) print offset satzanfang ;Satz auf Bildschirm anzeigen print offset crlf fclose hFile print "Gelesen wurde die Direktzugriffsdatei ",0 print offset fname print offset crlf mov eax,TRUE ret Main ENDP end start |
Interpretation des Übungsprogramms zum direkten Lesen eines Satzes einer Direktzugriffsdateisatznr dw 32: Hier ist die Satznummer des testweise zu lesenden Datensatzes eingetragen. Es hätte auch eine Definition im Sinne von satznr equ 32 gereicht.dateianfang + (satznr - 1) * satzlaenge: Die Formel zum Ermitteln der Satzposition in der der Datei gilt, wenn die erste Satznummer der Datei 1 ist. Es wäre etwas einfacher, wenn die erste Satznummer mit 0 benannt wäre! mov ax,satznr: Eigentlich müsste hier eax statt ax verwendet werden. Da unsere Datei deutlich weniger als 65535 Sätze enthält und vorher eax in gesamter Breite auf 0 gesetzt wurde, funktioniert das Übungsprogramm auch so. Die gleiche Aussage gilt für das folgende dec ax. mov bl,satzlaenge: Die gesamte Programmierung der nachfolgenden Multiplikation ist darauf abgestellt, dass die Satzlänge maximal 255 sein darf. Bei längeren Sätzen oder über 65535 Sätzen in der Datei müsste man ggf. beispielsweise bx oder gar ebx verwenden.[Befehlsbeschreibung von MUL] mov cloc, fseek(hFile,eax,FILE_BEGIN): Hier wird zum Positionieren die ermittelte Positionsangabe im Register eax genutzt. |