-
Notifications
You must be signed in to change notification settings - Fork 0
/
FILE.ASM
executable file
·286 lines (214 loc) · 6.48 KB
/
FILE.ASM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
.MODEL SMALL
.DATA
INCLUDE const.inc
fcb STRUC
drive_id DB 00h ; default drive
filename DB 8 DUP(0)
extension DB 3 DUP(0)
curr_block DW 00h
rec_size DW 00h
file_size DW 2 DUP(0)
date DB 2 DUP(0)
time DB 2 DUP(0)
reserved DB 8 DUP(0)
curr_rec DB 00h
random_rec DW 2 DUP(0)
fcb ENDS
file fcb <> ; file structure
file_mem_buf DW 00h ; file buffer segment address
fname_buf DB 12 DUP(0) ; file name buffer
file_str DB CR,LF,"enter file name: ",'$'
file_size_str DB CR,LF,"file size: ",'$'
PUBLIC file_mem_buf
.CODE
INCLUDE macros.inc
PUBLIC open_file
PUBLIC create_file
PUBLIC read_from_file
PUBLIC write_to_file
PUBLIC close_file
EXTRN read_str:NEAR
EXTRN print_number:NEAR
; Opens file. Z=0 if error.
;
; destroys ax,dx,cx,si,di
open_file PROC NEAR
mov bx,OFFSET file_str
print_string @data,bx
mov ax,SEG fname_buf
mov es,ax
mov di,OFFSET fname_buf
mov si,12
call NEAR PTR read_str
mov si,OFFSET fname_buf
mov ax,SEG file
mov es,ax
mov di,OFFSET file
mov al,1 ; scan off leading file name separators
mov ah,29h ; parse filename into file
int 21h
or al,al ; and check status
jnz open_file_end ; terminate prematurely on error
mov dx,OFFSET file ; open file
mov ah,0fh
int 21h
or al,al ; and check status
jnz open_file_end ; terminate prematurely on error
pushf ; preserve status
mov bx,OFFSET file_size_str ; print file size string
print_string @data,bx
sub sp,4
mov bx,sp
mov ax,file.file_size ; copy file size to stack parameter for
mov word ptr ss:[bx],ax ; print number
mov ax,file.file_size + 2
mov word ptr ss:[bx+2],ax
call NEAR PTR print_number ; print size number
add sp,4 ; restore stack
popf ; restore status
open_file_end:
retn
ENDP
; Creates file. Z=0 if error.
;
; destroys ax,dx,cx,si,di
create_file PROC NEAR
mov bx,OFFSET file_str ; print file name string
print_string @data,bx
mov ax,SEG fname_buf ; read file name string
mov es,ax
mov di,OFFSET fname_buf
mov si,12
call NEAR PTR read_str
mov si,OFFSET fname_buf
mov ax,SEG file
mov es,ax
mov di,OFFSET file
mov al,1 ; scan off leading file name separators
mov ah,29h ; parse filename into file
int 21h
or al,al ; and check status
jnz create_file_end ; terminate prematurely on error
mov dx,OFFSET file ; create file
mov ah,16h
int 21h
or al,al ; and check status
create_file_end:
retn
ENDP
; Reads single byte from file to file_mem_buf. Z=0 if error.
; al=01 or al=03 if EOF. Returns number of read_bytes in bx.
;
; destroys ax,dx,bx
read_from_file PROC NEAR
push ds
mov ds,file_mem_buf ; set disk transfer area to file_mem_buf
mov dx,0
mov ah,1ah
int 21h
pop ds
mov file.rec_size,F_BUF_SIZE ; and set the record size to F_BUF_SIZE bytes
mov dx,OFFSET file ; read from file
mov ah,14h
int 21h
mov bx,F_BUF_SIZE ; set the default length of bytes read
or al,al ; check status
pushf
jz read_from_file_end
cmp al,1 ; if EOF then do nothing more
jz read_from_file_end
cmp al,3 ; if partial record read at EOF then calculate
jnz read_from_file_end ; read length
push ax ; save al
mov dx,file.file_size+2 ; divide file.file_size by F_BUF_SIZE
mov ax,file.file_size
mov bx,F_BUF_SIZE
div bx
mov bx,dx ; copy tail number of bytes to bx
pop ax ; restore al
read_from_file_end:
popf
retn
ENDP
; Writes si bytes in file_mem_buf to file. Z=0 if error.
;
; destroys dx,ax,bx,cx,si,di
write_to_file PROC NEAR
push ds
mov ds,file_mem_buf ; set disk transfer area to file_mem_buf
mov dx,0
mov ah,1ah
int 21h
pop ds
cmp si,F_BUF_SIZE-1 ; if si is equal to buffer size
je write_to_file2 ; then proceed with sequential write
mov ax,file.file_size ; else set random_record to file size
mov file.random_rec,ax
mov ax,file.file_size+2
mov file.random_rec+2,ax
mov file.rec_size,1 ; and set the record size to 1 byte
mov cx,si ; set cx to the number of bytes in buffer
inc cx
push es ; preserve es segment register
mov es,file_mem_buf ; set es segment register to file_mem_buf
xor si,si
xor di,di
write_to_file1:
mov dx,OFFSET file ; write single byte from file_mem_buf
mov ah,22h
int 21h
or al,al ; check and preserve status
pushf
clc
add file.random_rec,1 ; increment random_record
adc file.random_rec+1,0
adc file.random_rec+2,0
adc file.random_rec+3,0
inc si ; write next byte in file_mem_buf to 1st
mov al,es:si ; position
mov es:di,al
popf ; restore check status
loope write_to_file1 ; loop while cx !=0 and Z=1
pop es ; restore es segment register
retn ; end writing to file
write_to_file2:
mov file.rec_size,si ; set file rec_size to the size of whole
inc file.rec_size ; buffer
mov dx,OFFSET file ; write contents in buffer sequentially
mov ah,15h
int 21h
or al,al
retn
ENDP
; Closes file. Z=0 if error.
;
; destroys ax,dx
close_file PROC NEAR
mov dx,OFFSET file ; close file with designated fcb
mov ah,10h
int 21h
or al,al ; check status
pushf ; preserve status
call clear_fcb ; and clear the file fcb
popf ; restore status
retn
ENDP
; Clears FCB.
;
; destroys ax
clear_fcb PROC
push es
push di
push cx
mov ax,SEG file
mov es,ax
mov di,OFFSET file
mov cx,SIZE fcb
mov al,0
rep stosb
pop cx
pop di
pop es
ret
ENDP
END