.data badArgsMsg: .string "Bad arguments - expected filename to print\n" baMsgEnd: .equ baMsgLen, baMsgEnd -badArgsMsg fileNotFoundMsg: .string "Input file not found\n" fnfMsgEnd: .equ fnfMsgLen, fnfMsgEnd-fileNotFoundMsg buf: .byte .text .global _start _start: popl %ecx # pop argument count cmpl $2,%ecx # expected: prog name, source jne badArgs popl %ebx # skip the name of the program popl %ebx # pop an (1st) argument address # try to open input file movl $5,%eax # sys_open() # ebx - ptr to filename movl $0,%ecx # flags movl $0,%edx # mode - unimportant when no new file created int $0x80 cmpl $254,%eax # -1 ja fileNotFound movl %eax,%ebx # file descriptor for sys_read(fd,buf,count) cpyLoop: movl $3,%eax # sys_read() movl $buf,%ecx movl $1,%edx int $0x80 cmpl $1,%eax jne eof # write buf to stdout pushl %ebx movl $4,%eax # system call number (sys_write) movl $1,%ebx # ebx = file descriptor (stdout) movl $buf,%ecx movl $1,%edx int $0x80 # call kernel (ecx and edx are already set before) popl %ebx jmp cpyLoop eof: movl $6,%eax # sys_close() # ebx= file handle int $0x80 # call kernel exit: movl $1,%eax # system call number (sys_exit) movl $0,%ebx # first syscall argument: exit code int $0x80 # call kernel badArgs: # write msg to stdout movl $4,%eax # sys_write() movl $1,%ebx # ebx = file descriptor (stdout) movl $badArgsMsg,%ecx movl $baMsgLen,%edx # length int $0x80 jmp exit fileNotFound: # write msg to stdout movl $4,%eax # sys_write() movl $1,%ebx # ebx = file descriptor (stdout) movl $fileNotFoundMsg,%ecx movl $fnfMsgLen,%edx # length int $0x80 jmp exit