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