section .data global errno errno: dd 0 section .text global sys_write global sys_read ; global sys_putval ; global sys_print ; global sys_getch global sys_lseek global sys_sleep global sys_exit global sys_fork global sys_wait global sys_exec global sys_execve global sys_open global sys_close global sys_uname global sys_waitpid global sys_poll global sys_mmap global sys_munmap global sys_pipe global sys_getpid global sys_dup global sys_setring global sys_sendmsg global sys_recvmsg extern unreal_main extern _the_entry_point global _start ; this function is jumped to at the end of certain syscall stubs. ; if the value in eax is negative, then it inverts it and saves ; to the errno memory location then sets eax to -1. ; otherwise it does nothing. syscall_errno_check: cmp eax,0 jge syscall_errno_check.is_ok not eax ; get non-negative value inc eax mov [errno],eax ; store it in errno. mov eax,-1 .is_ok: ret sys_write: push ebx mov eax,4 ; syscall number mov ebx, [esp+8] ; file descriptor mov ecx, [esp+12] ; buffer mov edx, [esp+16] ; count int 0x30 pop ebx jmp syscall_errno_check ; same as *nix read(2) system call. sys_read: push ebx mov eax,3 ; syscall number mov ebx, [esp+8] ; file descriptor mov ecx, [esp+12] ; buffer mov edx, [esp+16] ; count int 0x30 pop ebx jmp syscall_errno_check ; sleeps for at least the time provided on the stack. sys_sleep: mov eax, 5 ; syscall number mov ecx, [esp+4] int 0x30 ret ; Exits the current program with the error code provided on the stack. sys_exit: mov eax, 6 mov ecx, [esp+4] int 0x30 ret ; doesn't actually return.... ; get the process id of the calling program. sys_getpid: mov eax, 7 int 0x30 ret sys_lseek: push ebx ; preserve bx mov eax,8 ; syscall number mov ebx, [esp+8] ; file descriptor mov ecx, [esp+12] ; offset mov edx, [esp+16] ; whence int 0x30 pop ebx jmp syscall_errno_check sys_fork: ; gets a character from stdin. mov eax, 9 ; syscall number int 0x30 jmp syscall_errno_check sys_wait: ; gets a character from stdin. mov eax, 10 ; syscall number int 0x30 mov edx,[esp+4] ; get the pointer for the status code. mov [edx],ecx ; save it. ret sys_exec: ; executes the file open as fd. mov eax, 11 ; syscall number mov ecx,[esp+4] ; file descriptor int 0x30 jmp syscall_errno_check sys_open: ; opens a new file mov eax, 12 ; syscall number mov ecx,[esp+4] ; file name mov edx,[esp+8] ; file mode int 0x30 jmp syscall_errno_check sys_close: ; closes the specified file mov eax, 13 ; syscall number mov ecx,[esp+4] ; file descriptor int 0x30 ret ; no errors for close. sys_uname: ; gets info about the OS mov eax, 14 ; syscall number mov ecx,[esp+4] ; pointer to structure int 0x30 jmp syscall_errno_check sys_execve: ; executes the file open as fd. mov eax, 15 ; syscall number mov ecx,[esp+4] ; file descriptor mov edx,[esp+8] int 0x30 jmp syscall_errno_check sys_waitpid: ; executes the file open as fd. push ebx mov eax, 16 ; syscall number mov ebx,[esp+8] ; pid ; status isn't passed in mov edx,[esp+16] ; options int 0x30 mov edx,[esp+12] ; get the status code address. mov [edx],ecx ; save it pop ebx jmp syscall_errno_check sys_poll: ; gets info about the OS mov eax, 17 ; syscall number push ebx mov ebx, [esp+8] mov ecx,[esp+12] ; file descriptor int 0x30 pop ebx jmp syscall_errno_check ; 12 u32 virt=curr->regs.ebx; ; 16 u32 len=curr->regs.ecx; ; 20 u32 prot=curr->regs.edx; ; 24 u32 flags=curr->regs.edi; ; 28 u32 fd=curr->regs.esi; ; 32 u32 offset=curr->regs.ebp; sys_mmap: mov eax,18 push ebx push ebp mov ebx, [esp+12] ; address mov ecx, [esp+16] ; length mov edx, [esp+20] ; prot mov edi, [esp+24] ; flags mov esi, [esp+28] ; fd mov ebp, [esp+32] int 0x30 pop ebp pop ebx jmp syscall_errno_check sys_munmap: mov eax,19 push ebx mov ebx, [esp+8] mov ecx, [esp+12] int 0x30 pop ebx jmp syscall_errno_check sys_setring: mov eax,20 mov ecx,[esp+4] int 0x30 jmp syscall_errno_check sys_pipe: push ebx mov eax,21 mov ebx, [esp+8] int 0x30 mov [ebx],ecx mov [ebx+4],edx pop ebx jmp syscall_errno_check sys_dup: ; u32 old_fd=curr->regs.ecx; ; u32 new_fd=curr->regs.edx; mov eax, 22 mov ecx,[esp+4] mov edx,[esp+8] int 0x30 jmp syscall_errno_check sys_recvmsg: mov eax,23 mov ecx,[esp+4] int 0x30 jmp syscall_errno_check sys_sendmsg: mov eax,24 mov ecx,[esp+4] int 0x30 jmp syscall_errno_check ; calls main(void), then calls exit with the return value. _start: push ebx push ecx call _the_entry_point push eax call sys_exit