section .data bufsize dw 1024 ; const size of buffer section .bss buf: resb 1024 ; reserve 1024 byte for read/write buffer section .text ; start of .text segment global _start ; goto entry point _start: pop ebx ; argc pop ebx ; argv[0] = progname pop ebx ; arg[1] = filename _open_: mov eax,5 ; syscall number for open() ; we have already the filename in ebx mov ecx,0 ; O_RDONLY, defined in fcntl.h int 80h ; call kernel ; filedescriptor in eax or errornumber test eax,eax ; test if it's valid js _ret_error_ ; if < 0 (=unsigned) goto error _file_fun_: push dword eax ; save filedescriptor on stack _read_: ; ssize_t read( int fd, void* buf, size_t count ); mov eax,3 ; read() pop ebx ; get filedescriptor from stack mov ecx,buf ; ADDRESS of buf mov edx,bufsize ; ADDRESS of bufsize int 80h ; call kernel test eax,eax ; check return value js _ret_error_ ; if < 0 (=unsigned) goto error _write_: mov edx,eax ; save count of read bytes for write() (= bytes to read) mov eax,4 ; system call for write() push dword ebx ; save filedescriptor on stack mov ebx,1 ; SDTOUT file descriptor ; ecx is already set up properly by _read_ with buf int 80h ; call kernel test eax,eax ; check return value js _ret_error_ ; if < 0 (=unsigned) goto error test edx,bufsize ; test if we have written ( and therefore read ) je _read_ ; read next chunk of data jne _ret_ok_ ; less than bufsize -> this is the last loop _ret_ok_: mov ebx,0 ; return 0 in case of success jmp _exit_ ; go out of here _ret_error_: mov ebx,eax ; put returncode of open, read or write call in ebx (in case of error) _exit_: mov eax,1 ; exit() call int 80h ; call kernel