;************************** ;* File Operations Demo * ;* Scan File on Harddisc * ;* 2010 H.V.Viehof * ;* Assembled with A86 * ;************************** ;________________ ; ; Stapelsegment : ;________________ stack segment stack word 'stack' dw 10 dup (?) stack ends ;_________________ ; ; Programmsegment: ;_________________ code segment public word 'prog' main: mov ax, seg datafix ; Hauptteil mov es, ax ; Extrasegment initialisieren mov bx, offset Intro ; Text anzeigen call output call GetName ; Unterprog. Dateinamen eingeben call OpenFile ; Unterprog. Datei oeffnen jc Fehler ; Oops, ein Fehler trat auf... call ReadFile ; Unterprog. Datei lesen und danach schliessen mov ax, seg datafix ; Textausgabe 'Suchbegriff eingeben' mov es, ax mov bx, offset Search call output mov ax, seg datavar ; Segmente korrekt setzen mov ds, ax mov es, ax mov di, offset ScanBuffer ; Suchbegriff dorthin call GetText ; Benutzereingabe: Suchbegriff call bul ; Suchprozedur jc Z4 ; Carryflag gesetzt = gefunden ;______________________________________________________________________ ; ; kelime yok! ;______________________________________________________________________ mov ax, seg datafix ; Textausgabe 'negativ' mov es, ax mov bx, offset false call output mov ax, seg datavar ; Textausgabe 'Suchbegriff' mov es, ax mov bx, offset ScanBuffer call output jmp Ende ;______________________________________________________________________ ; ; kelime var! ;______________________________________________________________________ Z4: mov ax, seg datafix ; Textausgabe 'positiv' mov es, ax mov bx, offset true call output mov ax, seg datavar ; Textausgabe 'Suchbegriff' mov es, ax mov bx, offset ScanBuffer call output Ende: mov ax, seg datafix ; Textausgabe 'Beenden / Weiter' mov es, ax mov bx, offset TheEnd call output mov ah, 7 ; warten auf Tastendruck int 021 cmp al, 'w' jz main mov ax, 04c00 ; gepl. Ende int 021 ;______________________________________________________________________ ; ; Ausgaberoutine fuer Nullterminierten String und Errormessage ;______________________________________________________________________ output: mov dl, es: [bx] ; Zeichen an Position [bx] laden cmp dl, 0 je ret mov ah, 2 int 021 inc bx jmp output Fehler: mov ax, seg datafix ; Ein Errorhandler falls Datei nicht gefunden mov ds, ax mov bx, offset Error call output jmp main ;______________________________________________________________________ ; ; Eingaberoutinen fuer Dateiname und Suchbegriff ;______________________________________________________________________ GetName: mov di, offset Filename mov ax, seg Filename ; Extrasegment initialisieren mov es, ax GetText: mov ah, 1 ; Int 021 Funktion 1: Zeichen von der Tastatur lesen int 021 and ax, 0ff ; nur das in al wird benötigt cmp al, 0d ; ist es die Enter Taste? jz JumpOut ; dann ist das hier fertig stosb ; im Namenspuffer speichern jmp GetText ; Und naechstes Zeichen holen JumpOut: mov al, 0 ; Schlusszeichen setzen stosb ret ;______________________________________________________________________ ; ; Dateioperationen ;______________________________________________________________________ OpenFile: mov ax, seg datavar mov ds, ax ; Datensegment festlegen xor al, al ; al = 0 die Datei wird nur lesend verwendet mov dx, OFFSET Filename ; dx zeigt auf den Dateinamen mov ah, 03D int 021 ; Datei oeffnen mov ds: [FileHandle], ax ; und Dateihandle sichern ret ReadFile: mov dx, OFFSET TextBuffer S1: mov bx, ds: [FileHandle] ; Handle nach BX mov cx, 512 ; Der Datenpuffer hat zwar Platz fuer 64000 Zeichen mov ah, 03F ; aber DOS/FAT16 liest nur 512 WIN/FAT33/NTFS wuerden 4096 akzeptieren int 021 ; Daten Lesen add dx, ax ; Pufferzeiger + Anzahl gelesener Bytes cmp ax, 0 jne S1 ; solange ax != 0 naechsten Datensatz lesen mov bx, dx ; Das Dateiende im Puffer ermitteln mov ds: b [bx], 0 ; und mit 0 markieren CloseFile: mov ah, 03E mov bx, ds: [FileHandle] int 021 ; Datei schliessen ret ;______________________________________________________________________ ; ; Die Suchmaschine ;______________________________________________________________________ bul: mov ax, seg datavar ; die Puffer befinden sich im ihrem eigenen Segment mov ds, ax mov es, ax cld ; immer Directionflag loeschen, denn man kennt den Status vorher nicht mov si, offset TextBuffer ; Indexregister fuer den zu durchsuchenden Text A1: mov bx, offset ScanBuffer ; Indexregister des Suchbegriffs A2: ds: lodsb ; ein Zeichen aus dem Textpuffer holen cmp al, 0 ; ist es Null? jz EOF_false ; dann wurde schon jetzt das Dateiende erreicht, siehe unten... cmp al, es: b [bx] ; wenn nicht Vergleichen wir es mit der Speicherstelle die bx zeigt jne A1 ; ist es ungleich dann bx auf Anfang und naechstes Byte des Textes holen inc bx ; ist es gleich, dann bx + 1: zeigt auf das naechste Byte des Suchbegriffs cmp es: b [bx], 0 ; die Null zeigt Ende des Suchbegriffs, also gibt es Uebereinstimmung :-) jnz A2 ; falls (noch) nicht pruefen wir die beiden naechsten Bytes stc ; Suchbegriff gefunden - darum das Carryflag setzen und ret ; zurueck EOF_false: clc ; Dateiende erreicht und Suchbegriff nicht gefunden... ret ; ohne Erfolgsmeldung zum Hauptquartier :-( code ends ;_______________ ; ; Datensegmente: ;_______________ datafix segment public word 'daten' Intro db 0a,0d,0a,0d db " ********************************************************************",0a,0d db " * File Scan - durchsucht Datei im aktuellen Arbeitsverzeichniss *",0a,0d db " * nach dem eingegebenen Suchbegriff 2010 Heinz Volker Viehof *",0a,0d db " ********************************************************************",0a,0d db 0a,0d,0a,0d db " Dateinamen eingeben: ",0 Error db " <<< Datei nicht gefunden! >>>" Search db 0a,0d db " Suchbegriff eingeben: ",0 false db " enthaelt nicht den Suchbegriff: ",0 true db " enthaelt den Suchbegriff: ",0 TheEnd db 0a,0d db " [W]eitere Datei durchsuchen oder mit anderer Taste Programm beenden?",0 datafix ends datavar segment public word 'daten' FileHandle dw ? ScanBuffer db 128 dup (?) Filename DB 128 dup (?) TextBuffer DB 64000 dup (?) datavar ends end