Home

Sequentielles und direktes Lesen
von Sätzen einer Direktzugriffsdatei

Die ganze Datei lesen und schreiben:
InputFile und OutputFile

Übersicht
Dateizugriffe

MASM32
Infoseite

MASM32-SDK (Direktzugriffsdateien bei Windows Konsolapplikationen:)
Direktes Update von Sätzen einer Direktzugriffsdatei

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>
Links:
Mit einem zweimaligen Ablauf des Übungsprogramms lässt sich die Funktion nachweisen.
Direktes Update eines Satzes einer Direktzugriffsdatei
Hinweise 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/masm32-2.php#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 Direktzugriffsdatei
;Pruefen, 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
Letztes Upload: 22.02.2019 um 19:37:04