//----------------------------------------------------------------- // file2app.s // // This program shows the basic steps needed to read a file. // // to assemble: $ as file2app.s -o file2app.o // and to link: $ ld file2app.o -o file2app // // programmer: ALLAN CRUSE // written on: 16 FEB 2009 //----------------------------------------------------------------- .equ sys_READ, 0 # system-call ID-number .equ sys_WRITE, 1 # system-call ID-number .equ sys_OPEN, 2 # system-call ID-number .equ sys_CLOSE, 3 # system-call ID-number .equ sys_LSEEK, 8 # system-call ID-number .equ sys_EXIT, 60 # system-call ID-number .equ dev_STDOUT, 1 # device-file ID-number .equ O_RDONLY, 0 # access-method flag .equ SEEK_END, 2 # flag for lseek-method .equ SEEK_SET, 0 # flag for lseek-method .section .data handle: .quad -1 # for storing file-handle flags: .quad O_RDONLY # for type of file-access fname: .asciz "mycookie.dat" # for storing file's name fsize: .quad -1 # for storing file-length inchr: .space 1 # buffer for file input .section .text _start: # open the file for reading mov $sys_OPEN, %rax # specify the service-ID lea fname, %rdi # pointer to file's name mov flags, %rsi # how we access the file syscall # invoke kernel service mov %rax, handle # preserve return-value # TODO: need to check for a 'file open' failure # seek to the end-of-file mov $sys_LSEEK, %rax # specify the service-ID mov handle, %rdi # setup file's 'handle' mov $0, %rsi # specify offset to seek mov $SEEK_END, %rdx # specify the seek mode syscall # invoke kernel service mov %rax, fsize # seek to the file's beginning mov $sys_LSEEK, %rax # specify the service-ID mov handle, %rdi # setup file's 'handle' mov $0, %rsi # specify offset to seek mov $SEEK_SET, %rdx # specify the seek mode syscall # invoke kernel service # main loop to read and display file's contents nxin: cmpq $0, fsize # bytes left to read? jle finis # no, loop is finished mov $sys_READ, %rax # specify the service-ID mov handle, %rdi # setup file's 'handle' lea inchr, %rsi # point to input buffer mov $1, %rdx # specify buffer's size syscall # invoke kernel service mov $sys_WRITE, %rax # specify the service-ID mov $dev_STDOUT, %rdi # setup device's handle lea inchr, %rsi # point to output buffer mov $1, %rdx # specify buffer's size syscall # invoke kernel service decq fsize # one less byte to read jmp nxin # again for more input finis: # close the file mov $sys_CLOSE, %rax # specify the service-ID mov handle, %rdi # setup file's 'handle' syscall # invoke kernel service # terminate this program mov $sys_EXIT, %rax # specify the service-ID mov $0, %rdi # use zero as exit-code syscall # invoke kernel service .global _start # make entry-point visible .end # nothing else to assemble