Dies Übungsprogramm zum Update eines Satzes ist aus dem Übungsprogramm zum direkten Lesen abgeleitet: Es wird ein einziger Satz der Direktzugriffsdatei verändert. Vor der Änderung und nach der Änderung wird der geänderte Satz auf dem Bildschirm angezeigt.
Der Abschnitt zum Ermitteln der Zieladresse wurde in einem Makro untergebracht. Bei dieser Gelegenheit wurde die dabei genutzte Logik etwas geschickter programmiert. Die angeforderte Satznummer wird auf ihre Zulässigkeit überprüft. Sie muss im Bereich von 1 bis 50 liegen. Ohne eine solche Prüfung würde eine angeforderte Satznummer über 50 zu einer Vergrößerung der Datei führen. Weiterhin wird geprüft, ob der Schreibbefehl fwrite tatsächlich geschrieben hat. Die Funktion dieser Überprüfung lässt sich testen, indem man die Datei mit dem Schreibschutzattribut nur lesen ausstattet: attrib \temp\versuch.txt +r. Eine ähnliche Überprüfung erfolgt unmittelbar nach dem Lesebefehl fread, denn es hatte sich gezeigt, dass sich die Datei bei gesetztem Attribut nur lesen in Verbindung mit der Dateiöffnung im Update-Modus nicht lesen lässt. Es ist offensichtlich, dass bereits diese Überprüfungen das Programm deutlich komplizierter gemacht haben. Auch dauert das Testen länger, denn jede programmierte Überprüfung erfordert weitere Teste. C:\masm32\Uebung\Konsole>goto TheEnd C:\masm32\Uebung\Konsole>int2ascwritedirect.exe vor Satzupdate: 0041. Datensatz nach Satzupdate: Teddy ist ein grosser Grizzlybaer!aaaaaaaaaaaaaaaa Update erfolgte in die Direktzugriffsdatei C:\temp\versuch.txt Press any key to continue ... C:\masm32\Uebung\Konsole>int2ascwritedirect.exe vor Satzupdate: Teddy ist ein grosser Grizzlybaer!aaaaaaaaaaaaaaaa nach Satzupdate: Teddy ist ein grosser Grizzlybaer!aaaaaaaaaaaaaaaa Update erfolgte in die Direktzugriffsdatei C:\temp\versuch.txt Press any key to continue ... C:\masm32\Uebung\Konsole> Mit einem zweimaligen Ablauf des Übungsprogramms lässt sich die Funktion nachweisen. |
Direktes Update eines Satzes einer DirektzugriffsdateiHinweise zum Programmablauf stehen hinter dem Programmlisting.comment * --------------------------- Uebungsprogramm zum Update 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 ;-------------- ; Das MAKRO ziel ermittelt Zieladresse innerhalb der Direktzugriffsdatei ; bufferanfang + (satznr - 1) * satzlaenge ;-------------- ziel MACRO ;;-------------- ;; ermittelt Zieladresse innerhalb der Direktzugriffsdatei ;; bufferanfang + (satznr - 1) * satzlaenge ;;-------------- mov eax,satznr ;;satznr - 1 dec eax mov bl,satzlaenge mul bl ;;abstand ab anfang datei nun in eax ENDM ; Konstanten ; ------------------------------------------------ .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 ; Mit folgendem Satz erfolgt die Aenderung satzmod db 'Teddy ist ein grosser Grizzlybaer!' lsatzmod equ $ - satzmod lfill equ satzlaenge - lsatzmod db lfill dup('a') db 0 ;Satzende fuer ASCIIZ ;Defaultwerte fname db 'C:\temp\versuch.txt',0 lfname equ $ - fname crlf db 13,10,0 satznr dword 41 .code start: SetConsoleCaption "Sequentielles Lesen eine Direktzugriffsdatei" invoke Main inkey invoke ExitProcess,eax ;------------------------------- Main PROC LOCAL hFile :DWORD LOCAL rval :DWORD ;Anzahl gelesener Bytes LOCAL cloc :DWORD ;Position in Datei ;-------------- ;Pruefen, ob Satznummer zulaessig ;-------------- mov eax,satznr cmp eax,1 jl @F cmp eax,satzanzahl jg @F jmp start10 @@: print "Abbruch! Satznummerbereich nur von 1 bis 50",13,10,0 mov eax,FALSE jmp raus ;------------ ;Datei zum Update oeffnen ;------------ start10: mov hFile, fopen(ADDR fname) ;open the file ;-------------- ; Ermittelt Zieladresse innerhalb der Direktzugriffsdatei ; bufferanfang + (satznr - 1) * satzlaenge ;-------------- ziel ;abstand ab anfang datei nun in eax push eax ;position sichern mov cloc, fseek(hFile,eax,FILE_BEGIN) mov rval, fread(hFile,ADDR satzanfang,satzlaenge) mov eax,rval or eax,eax ;eax ist 0, wenn die Datei nicht gelesen werden konnte jne @F print "Abbruch! Die Datei konnte nicht gelesen werden.",13,10,0 pop eax ;Stack abraeumen mov eax,FALSE jmp raus @@: print "vor Satzupdate: ",0 print offset satzanfang ;Satz auf Bildschirm anzeigen print offset crlf pop eax ;position push eax mov cloc, fseek(hFile,eax,FILE_BEGIN) mov rval, fwrite(hFile,ADDR satzmod,satzlaenge) mov eax,rval or eax,eax ;eax ist 0, wenn nichts geschrieben wurde jne @F fclose hFile print "Abbruch! Es konnte nicht in die Datei geschrieben werden",13,10,0 pop eax ;Stack abraeumen mov eax,FALSE jmp raus @@: pop eax ;position mov cloc, fseek(hFile,eax,FILE_BEGIN) mov rval, fread(hFile,ADDR satzanfang,satzlaenge) print "nach Satzupdate: ",0 print offset satzanfang ;Satz auf Bildschirm anzeigen print offset crlf fclose hFile print "Update erfolgte in die Direktzugriffsdatei ",0 print offset fname print offset crlf mov eax,TRUE raus: ret Main ENDP end start |
Interpretation des Übungsprogrammes zum direkten Update eines Satzes einer DirektzugriffsdateiPruefen, ob Satznummer zulaessig: Es wird geprüft, ob die in der Variablen satznr enthaltene Satznummer im zulässigen Bereich von 1 bis satzanzahl ist. Im Text der zugehörigen Fehlermeldung kann satzanzahl anstelle von 50 nicht benutzt werden, denn Text erfordert ASCII-Codierung.mov eax,rval: Nach den Lese- und Schreibbefehlern ist dieser Befehl doppelt gemoppelt: Wie ein Blick auf die beiden Makros fread und fwrite in masm32\macros\macros.asm zeigt, übergeben sie ihren Rückgabewert bereits in eax. Beim Auftreten des Fehlers bei bereits geöffneter Datei sollte vor der vorzeitigen Programmbeendigung die Datei geschlossen werden und der Stack von Daten bereinigt werden: fclose hFile print "Abbruch! Es konnte nicht in die Datei geschrieben werden",13,10,0 pop eax |