Fajlovi i kako ih koristiti

Fajlovi mogu da se otvore da se citaju i da se u njih upisuje. U DOS-u vec postoje rutine za to, tako da mi ne moramo da ih pisemo. Da, jos prekida. Ovde je sada predstavljen spisak korisnih funkcija prekida 21h preko koga manipulisemo fajlovima.

Bitno: Bitovi se broje sleva na desno.

Funkcija 3Dh: otvori fajl
Otvara postojeci fajl na specificiranom drajvu sa datim imenom za citanje ili pisanje.

ULAZ:

AH = 3Dh
AL = bitovi 0-2 mod koriscenja

bitovi 4-6 mod deljivosti (DOS 3+) DS:DX = segment:offset ASCIIZ imena putanje

IZLAZ:

CF = 0 funkcija je uspesno izvrsena
AX = handle
CF = 1 dogodila se neka greska
AX = kod greske

Sta znaci ASCIIZ? ASCIIZ string je ASCII string ali se zavrsava sa nulom umesto sa dolar ($) simbolom.

Bitno: Treba zapamtiti handle fajla jer nam je potreban za kasnije.

Kako sacuvati file handle

Veoma je bitno da sacuvate handle fajla jer nam je on potreban ako zelimo nesto da radimo sa fajlom. Kako se to radi? Postoje dve metode: KOpirajte handle u neki drugi registar i vise ne koristite taj registar sem za handle ili da iskopirate u promenljivu u memoriji.

Mana prvog metoda je da morate da pamtite da ne koristite taj registar a i onda imate jedan registar manje na raspolaganju a moze se iskoristiti za nesto drugo. Mi cemo, iz ociglednih razloga, koristiti drugi metod. Evo kako se to radi:

HandleFajla DW 0 	; ovu promenljivu koristimo da sacuvamo handle
.
.
.
mov HandleFajla,ax 	; cuvamo handle fajla
Funkcija 3Eh: zatvaranje fajla
Zatvara fajl koji je bio otvoren.

ULAZ:

AX = 3Eh
BX = handle fajla

IZLAZ:

CF = 0 funkcija je uspesno izvrsena
AX = unistena mu je vrednost
CF = 1 funkcija se nije izvrsila
AX = kod greske - 06h fajl nije otvoren ili nepravilan handle.

Bitno: Ne pozivajte ovu funkciju sa handle-om nula, jer ce to zatvoriti standardni ulaz preko tastature i vise necete moci da unosite bilo sta sa tastature.

Funkcija 3Fh: citaj fajl/uredjaj

Cita bajt iz fajla ili uredjaja u bafer.

ULAZ:

AH = 3Fh
BX = handle
CX = broj bajtova koji ce se procitati
DS:DX = segment:offset bufera

IZLAZ:

CF = 0 funkcija je uspesno izvrsena
AX = broj procitanih bajtova
CF = 1 dogodila se neka greska

Ako je CF = 0 i AX = 0 ondfa je pokazivac fajla vec stigao na kraj fajla i vise ne moze nista da se procita. Ako je CF = 0 a AX je manji od CX onda je procitan samo deo jer smo stigli do kraja fajla ili se desila neka greska.

Ova funkcija se moze koristiti i za uzimanje podatka sa tastature. Koristi se handle nula i prestaje sa citanjem posle prvog prenosa ili kada je odredjeni broj bajtova procitan. Ovo je dobra stvar ako je potrebno da korisnik unese odredjeni broj karaktera.

Listing 7: 7.asm

; program koji demonstrira citanje iz vec kreirano fajla
; da bi program radio na C:\ morate da kreirate test.txt i da unesete neki tekst

.model small
.stack

.data
Handle DW ?                  ; da smestimo handle 
ImeFajla DB "C:\test.txt",0  ; fajl koji cemo otvoriti
OtvaranjeError DB " * Greska (pri otvaranju)! *$"
CitanjeError   DB " * Greska (pri citanju)! *$"
Bafer    DB 100 dup (?)  ; buffer to store data

.code 

mov ax,@data                 
mov ds,ax                    

mov dx,OFFSET ImeFajla       ; adresa ImeFajla u dx 
mov al,2                     ; mod koriscenja - citaj i pisi
mov ah,3Dh                   ; funkcija 3Dh - otvori fajl
int 21h                      ; poziv DOS servisa

mov Handle,ax                ; sacuvaj handle fajla za kasnije
jc GreskaOtvaranje           ; skoci akoje CF=1 - greska!

mov dx,offset Bafer          ; adresa bafera u dx
mov bx,Handle                ; handle u bx
mov cx,100                   ; broj bajtova za citanje
mov ah,3Fh                   ; funkcija 3Fh - citaj iz fajla
int 21h                      ; poziv DOS servisa

jc GreskaCitanje             ; skoci akoje CF=1 - greska! 

mov bx,Handle                ; stai handle fajla u bx 
mov ah,3Eh                   ; funkcija 3Eh - zatvori fajl
int 21h                      ; poziv DOS servisa

mov cx,100                   ; duzina stringa
mov si,OFFSET Bafer          ; DS:SI - adresa stringa
xor bh,bh                    ; video strana - 0
mov ah,0Eh                   ; funkcija 0Eh - pisi karakter

NextChar:

lodsb                        ; AL = sledeci karakter u stringu
int 10h                      ; poziv BIOS servisa
loop NextChar

mov ax,4C00h                 ; zavrsite program 
int 21h 

GreskaOtvaranje:

mov dx,offset OtvaranjeError ; prikazi poruku o gresc
mov ah,09h                   ; koristeci funkciju 09h
int 21h                      ; poziv DOS servisa
mov ax,4C01h                 ; zavrsi program sa nivoom greske =1 
int 21h 

GreskaCitanje:

mov dx,offset CitanjeError   ; prikazi poruku o gresci 
mov ah,09h                   ; koristeci funkciju 09h
int 21h                      ; poziv DOS servisa
mov ax,4C02h                 ; zavrsi program sa nivoom greske =2 
int 21h


END

Funkcija 3Ch: kreiranje fajla

Kreira prazan fajl na specificiranom drajvu sa specifiranim imenom.

ULAZ:

AH = 3Ch
CX = atributi fajla

bit 0 = 1 fajl samo za citanje
bit 1 = 1 skriveni fajl
bit 2 = 1 sistemski fajl
bit 3 = 1 jacina (ignorise se)
bit 4 = 1 rezervisano (0) - direktorijum
bit 5 = 1 bit arhive
bits 6-15 rezervisano (0)
DS:DX = segment:offset ASCIIZ imena putanje

IZLAZ:

CF = 0 funkcija je uspesno izvrsena
AX = handle
CF = 1 dogodila se neka greska

03h putanja nije nadjena
04h nema handlea
05h zabranjen pristup

Bitno: Ako postoji fajl sa istim imenom kao ovaj koji kreiramo, onda ce originalni fajl biti obrisan. Budite sigurni da nema fajla sa tim imenom tamo gde ga kreirate, a to se moze ispitati sa sledecom funkcijom.

Funkcija 4Eh: nadji prvi isti fajl

Trazi prvi fajl koji je isti kao zadati fajl.

ULAZ:

AH = 4Eh CX = mask za atribute fajla (bitovi se mogu kombinovati)

bit 0 = 1 samo citanje
bit 1 = 1 sakriven
bit 2 = 1 sistemski
bit 3 = 1 volume labela
bit 4 = 1 direktorijum
bit 5 = 1 arhiva
bit 6-15 rezervisano
DS:DX = segment:offset ASCIIZ imena putanje

IZLAZ:

CF = 0 funkcija je uspesno izvrsena
[DTA] Disk Transfer Area = Nadji prvi data blok

DTA blok:

Offset   Velicina [bajt]  Znacenje

0        21               Rezervisano
21       1                Atributi fajla
22       2                Vreme poslednje modifikacije
24       2                Datum poslednje modifikacije
26       4                Velicina fajla [bajt]
30       13               Ime fajla (ASCIIZ)

Primer provere da li fajl vec postoji:
Fajl DB "C:\fajl.txt",0	     ; ime fajla koje mi hocemo
mov dx,OFFSET Fajl           ; adresa imena fajla
mov cx,3Fh                   ; maska fajla 3Fh - bilo koji fajl
mov ah,4Eh                   ; funkcija 4Eh - nadji prvi fajl
int 21h                      ; poziv DOS servisa

jc NemaFajla

; stampamo poruku koja kaze da fajl postoji

NemaFajla:

; nastavljamo sa kreiranjem fajla
Ovo je primer kreiranja praznog fajla i onda upisivanja u njega.
Listing 8: 8.asm

; Ovaj program kreira fajl i onda upisuje u njega.

.model small
.stack

.data 
CR equ 13
LF equ 10

StartPoruka DB "Ovaj program kreira fajl koji se zove NOVI.TXT na C drajvu.$"
EndPoruka   DB CR,LF,"Fajl je korektno kreiran, pogledajte u fajl da bi ste bili sigurni.$"

PorukaUpis       DB " * Greska (prilikom pisanja)! *$"
PorukaOtvaranje  DB " * Greska (prilikom otvaranja)! *$"
PorukaKreiranje  DB " * Greska (prilikom kreiranja)! *$"

Upisi    DB " ZDRAVO, OVO JE TEST, DA LI JE USPEO?",0 
                             ;37 bajtova za upis + nula = 38 
ImeFajla DB "C:\novi.txt",0  ; ime fajla koji cemo otvoriti 
Handle   DW ? 	             ; za handle fajla
.code 

mov ax,@data 	 
mov ds,ax  
mov dx,offset StartPoruka 
mov ah,09h 
int 21h 

mov dx,offset ImeFajla       ; adresa ImeFajla u dx 
xor cx,cx                    ; obrisi cx - napravi obican fajl
mov ah,3Ch                   ; funkcija 3Ch - kreiraj fajl
int 21h                      ; poziv dos servisa

jc GreskaKreiranja           ; skoci akoje CF=1 - greska!

mov dx,offset ImeFajla       ; adresa ImeFajla u dx
mov al,2                     ; mod koriscenja - citaj i pisi
mov ah,3Dh                   ; funkcija 3Dh - otvori fajl
int 21h                      ; poziv dos servisa

jc GreskaOtvaranja           ; skoci akoje CF=1 - greska!
mov Handle,ax                ; sacuvaj handle fajla za kasnije

mov dx,offset Upisi          ; adresa teksta za upis u fajl 
mov bx,Handle                ; handle fajla
mov cx,38                    ; 38 bajtova za upis
mov ah,40h                   ; funkcija 40h - pisi u fajl
int 21h                      ; poziv dos servisa

jc GreskaUpisivanja          ; skoci akoje CF=1 - greska!
cmp ax,cx                    ; jesu li svi podaci upisani?
jne GreskaUpisivanja                    ; ne nisu - greska!

mov bx,Handle                ; stavi handle fajla u bx 
mov ah,3Eh                   ; funkcija 3Eh - zatvori fajl
int 21h                      ; poziv dos servisa

mov dx,offset EndPoruka 
mov ah,09h 
int 21h 

ReturnToDOS:

mov ax,4C00h                  ; zavrsite program 
int 21h 

GreskaUpisivanja:
mov dx,offset PorukaUpis 
jmp KrajGreska

GreskaOtvaranja:
mov dx,offset PorukaOtvaranje 
jmp KrajGreska

GreskaKreiranja:
mov dx,offset PorukaKreiranje 

KrajGreska:
mov ah,09h 
int 21h 
mov ax,4C01h 
int 21h 



END
Ovo je primer brisanja fajla posle provere da li postoji:
Listing 9: 9.asm ; demonstrira brisanje fajla. Brisemo fajl novi.txt sa c drajva koji ; smo kreirali u predhodnom primeru. ; Takodje proveravamo prvo da li je fajl tamo. .model small .stack .data CR equ 13 LF equ 10 Fajl db "C:\novi.txt",0 Obrisan db "Obrisan je fajl c:\novi.txt $" NemaFajla db "c:\new.txt doesn't exits - exiting$" GreskaUBrisanju db "Can't delete file - probably write protected$" .code mov ax,@data mov ds,ax mov dx,OFFSET Fajl ; adresa imena fajla koji ce se brisati mov cx,3Fh ; maska fajla 3Fh - bilo koji fajl mov ah,4Eh ; funkcija 4Eh - nadji prvi fajl int 21h ; poziv DOS servisa jc FileDontExist mov dx,OFFSET Fajl ; DS:DX ukazuje na fajl koji treba obrisati mov ah,41h ; funkcija 41h - obrisi fajl int 21h ; poziv DOS servisa jc ErrorDeleting ; skok ako je CF=1 - greska mov dx,OFFSET Obrisan ; prikazi poruku jmp Endit ErrorDeleting: mov dx,OFFSET GreskaUBrisanju jmp Endit FileDontExist: mov dx,OFFSET NemaFajla EndIt: mov ah,9 int 21h mov ax,4C00h ; zavrsite program int 21h ; poziv DOS servisa end

Koriscenje FindFirst i FindNext funkcija

Listing 10: 10.asm

; ovaj program prikazuje kako treba traziti fajl.
; Stampa sve fajlove i direktorijume na drajvu C.

.model small
.stack

.data
CR equ 13
LF equ 10

Prazno   db CR,LF,"$"
ImeFajla db "c:\*.*",0  ; ime fajla
DTA 	 db 128 dup(?)  ; bafer za smestanje DTA 
PorukaG  db " * Nastala je greska - pri izlasku. *$"

.code

mov ax,@data 	 
mov ds,ax 	
mov es,ax               ;ovde smo dodali i es

mov dx,OFFSET DTA       ; DS:DX ukazuje na DTA 
mov ah,1AH              ; funkcija 1Ah - postavlja DTA
int 21h                 ; poziv DOS servisa

mov cx,3Fh              ; maska atributa - svi fajlovi
mov dx,OFFSET ImeFajla  ; DS:DX ukazuje na ASCIIZ ime fajla
mov ah,4Eh              ; funkcija 4Eh - nadji prvi fajl
int 21h                 ; poziv DOS servisa

jc greska               ; skok ako je CF=1 - greska
Nastavi:

mov dx,OFFSET Prazno 	; prikazuje poruku na ekranu (enter)
mov ah,9 		; koristeci funkciju 09h
int 21h 		; prekida 21h


mov dx,OFFSET ImeFajla  ; DS:DX ukazuje na ime fajla
mov ah,4Fh              ; funkcija 4fh - nadji sledeci fajl
int 21h                 ; poziv DOS servisa

jc izlaz                ; skok na IZLAZ ako je CF=1 - greska

mov cx,13               ; duzina imena fajla
mov si,OFFSET DTA+30    ; DS:SI ukazuje na ime fajla u DTA
xor bh,bh               ; video strana - 0
mov ah,0Eh              ; funkcija 0Eh - ispisi karakter

SledeciKar:

lodsb                   ; AL = sledeci karakter u stringu
int 10h                 ; poziv BIOS servisa

loop SledeciKar

mov di,OFFSET DTA+30    ; ES:DI ukazuje na DTA
mov cx,13               ; duzina imena fajla
xor al,al               ; napuni nulama
rep stosb               ; obrisi DTA

jmp Nastavi             ; nastavi sa trazenjem

greska: 

mov dx,OFFSET PorukaG   ; prikazi poruku o gresci
mov ah,9
int 21h

izlaz:

mov ax,4C00h            ; zavrsetak programa
int 21h

end

Sadrzaj