CSC231 readWriteTextFile.asm
Back to Class Page
;;; readWriteTextFile.asm
;;; D. Thiebaut
;;; Combining readTextFile.asm and writeTextFile.asm
;;; This program reads the contents of a text file,
;;; transforms all of its characters to uppercase, then
;;; stores the result back in the file.
;;;
%assign SYS_EXIT 1
%assign SYS_WRITE 4
%assign SYS_READ 3
%assign SYS_LSEEK 19
%assign SEEKSET 0
%assign STDOUT 1
%assign SYS_OPEN 5
%assign SYS_CLOSE 6
%assign SYS_CREATE 8
%assign O_RDONLY 000000q
%assign O_WRONLY 000001q
%assign O_RDWR 000002q
%assign O_CREAT 000100q
%assign S_IRUSR 00400q
%assign S_IWUSR 00200q
%assign S_IXUSR 00100q
;;; --- MACRO -----------------------------------------------
;;; print msg,length
%macro print 2 ; %1 = address %2 = # of chars
pushad ; save all registers
mov edx,%2
lea ecx,[%1]
mov eax,SYS_WRITE
mov ebx,STDOUT
int 0x80
popad ; restore all registers
%endmacro
;;; --- MACRO -----------------------------------------------
;;; print2 "quoted string"
%macro print2 1 ; %1 = immediate string,
section .data
%%str db %1
%%strL equ $-%%str
section .text
print %%str, %%strL
%endmacro
;;; --- MACRO -----------------------------------------------
;;; createFile filename, handle
%macro createFile 2
mov eax,SYS_CREATE
mov ebx,%1
mov ecx, S_IRUSR|S_IWUSR|S_IXUSR
int 0x80
test eax,eax
jns %%createfile
print2 "Could not open file"
mov eax,SYS_EXIT
mov ebx,0
int 0x80 ; final system call
%%createfile:
mov %2,eax ; save handle
%endmacro
;;; --- MACRO -----------------------------------------------
;;; openFile filename, mode, handle
%macro openFile 3
mov eax,SYS_OPEN
mov ebx,%1
mov ecx,%2
mov edx, S_IRUSR|S_IWUSR|S_IXUSR
int 0x80
test eax,eax
jns %%readFile
print2 "Could not open file"
mov eax,SYS_EXIT
mov ebx,0
int 0x80 ; final system call
%%readFile:
mov %3,eax ; save handle
%endmacro
;;; --- MACRO -----------------------------------------------
;;; readFile handle, buffer, buffer-length, number-bytes-read
%macro readFile 4
mov eax,SYS_READ
mov ebx,%1 ; file descriptor in bx
mov ecx,%2 ; buffer address
mov edx,%3 ; max number of bytes to read
int 0x80
mov %4,eax ; save number bytes read
%endmacro
;;; --- MACRO -----------------------------------------------
;;; writeBuf handle, buffer, noBytesToWrite
%macro writeFile 3
mov eax,SYS_WRITE
mov ebx,%1
mov ecx,%2
mov edx,%3
int 0x80
%endmacro
;;; --- MACRO -----------------------------------------------
;;; close handle
%macro close 1
mov eax,SYS_CLOSE
mov ebx,%1
int 0x80
%endmacro
;; -------------------------
;; data segment
;; -------------------------
section .data
fileName db "test.dat",0
handle dd 0
noRead dd 0
section .bss
MAXBUF equ 100000
buffer resb MAXBUF ; 100,000 bytes of storage
;; -------------------------
;; code area
;; -------------------------
section .text
global _start
_start:
;;; open the file and put its contents in Buffer.
;;; keep track of # of bytes read in noRead
openFile fileName, O_RDWR, [handle]
readFile [handle], buffer, MAXBUF, [noRead]
close [handle]
;;; transform buffer to uppercase
call toUpper
;;; write contents of buffer (noRead bytes) to same
;;; file
createFile fileName, [handle]
writeFile [handle], buffer, [noRead]
close [handle]
;; exit()
mov eax,SYS_EXIT
mov ebx,0
int 0x80 ; final system call
;;; -----------------------------------------------------------
;;; toUpper: transforms all the chars in buffer to uppercase.
;;; variable noRead contains # of valid chars.
;;; -----------------------------------------------------------
toUpper:
mov ecx,[noRead] ; get # of chars
mov ebx,buffer ; point to 1st char
.for: cmp byte[ebx],'a' ; less than 'a'?
jb .next
cmp byte[ebx],'z' ; greater than 'z'?
ja .next
add byte[ebx],'A'-'a' ; no... change it
.next: inc ebx
loop .for
ret