MASM32-SDK (Direktzugriffsdateien bei Windows Konsolapplikationen:)
Sequentielles und direktes Lesen von Sätzen einer Direktzugriffsdatei

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 ...
Das erste Übungsprogramm auf dieser Seite liest die vollständige Datei von vorn bis hinten sequenziell durch und zeigt jeden Satz auf dem Bildschirm an.

In verkürzter Darstellung sieht die Anzeige wie links gezeigt aus.

Sequenzielles Lesen der gesamten Direktzugriffsdatei
Hinweise 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 Befehlszeile
mov 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 Direktzugriffsdatei
Die 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 ...
Links ist der Ablauf des Übungsprogramms dargestellt. Gelesen wurde Datensatz 32.
Direktes Lesen eines Satzes einer Direktzugriffsdatei
Hinweise 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 Direktzugriffsdatei
satznr 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.

Letztes Upload: 14.07.2023 um 06:19:40 • Impressum und Datenschutzerklärung