LINE_FEED = 0Ah O_ACCMODE = 0003o O_RDONLY = 0000o O_WRONLY = 0001o O_RDWR = 0002o O_CREAT = 0100o O_EXCL = 0200o O_NOCTTY = 0400o O_TRUNC = 1000o O_APPEND = 2000o O_NONBLOCK = 4000o S_ISUID = 4000o S_ISGID = 2000o S_ISVTX = 1000o S_IRUSR = 0400o S_IWUSR = 0200o S_IXUSR = 0100o S_IRGRP = 0040o S_IWGRP = 0020o S_IXGRP = 0010o S_IROTH = 0004o S_IWOTH = 0002o S_IXOTH = 0001o system_init: mov eax,201 ; sys_time mov edi,timestamp syscall or [local_heap_available],1 retn system_shutdown: call mcheck retn open: ; in: edx - path to file ; out: ebx = file handle, cf set on error ; preserves: esi, edi push rsi rdi call adapt_path mov eax,2 ; sys_open mov esi,O_RDONLY xor edx,edx syscall pop rdi rsi test eax,eax js interface_error mov ebx,eax clc ret interface_error: stc ret adapt_path: xor ecx,ecx mov edi,path_buffer copy_path: mov al,[edx+ecx] cmp al,'\' jne path_char_ok mov al,'/' path_char_ok: cmp ecx,1000h jae out_of_memory mov [edi+ecx],al inc ecx test al,al jnz copy_path retn create: ; in: edx - path to file ; out: ebx = file handle, cf set on error ; preserves: esi, edi push rsi rdi call adapt_path mov esi,O_CREAT+O_TRUNC+O_WRONLY mov edx,S_IRUSR+S_IWUSR+S_IRGRP+S_IROTH mov eax,2 ; sys_open syscall pop rdi rsi test eax,eax js interface_error mov ebx,eax clc retn write: ; in: ebx = file handle, edx - data, ecx = number of bytes ; out: cf set on error ; preserves: ebx, esi, edi push rsi rdi mov eax,1 ; sys_write mov edi,ebx mov esi,edx mov edx,ecx syscall pop rdi rsi test eax,eax js interface_error cmp eax,edx jne interface_error clc ret read: ; in: ebx = file handle, edx - buffer, ecx = number of bytes ; out: cf set on error ; preserves: ebx, esi, edi push rsi rdi mov eax,0 ; sys_read mov edi,ebx mov esi,edx mov edx,ecx syscall pop rdi rsi test eax,eax js interface_error cmp eax,edx jne interface_error clc ret close: ; in: ebx = file handle ; preserves: ebx, esi, edi push rdi mov edi,ebx mov eax,3 ; sys_close syscall pop rdi ret lseek: ; in: ebx = file handle, cl = method, edx:eax = offset ; out: edx:eax = new offset from the beginning of file, cf set on error ; preserves: ebx, esi, edi push rsi rdi mov edi,ebx mov esi,edx mov eax,eax shl rsi,32 or rsi,rax xor edx,edx mov dl,cl mov eax,8 ; sys_lseek syscall pop rdi rsi cmp rax,-1 je interface_error mov rdx,rax shr rdx,32 clc ret get_timestamp: ; out: edx:eax = timestamp ; preserves: ebx, ecx, esi, edi ; note: during the passes of a single assembly this function should always return the same value mov eax,dword [timestamp] mov edx,dword [timestamp+4] retn display_string: ; in: ; esi - string ; ecx = string length, zero for ASCIIZ string ; preserves: ebx, esi push rbx rsi rbp test ecx,ecx jnz write_string_to_stdout xor al,al mov edi,esi or ecx,-1 repne scasb neg ecx sub ecx,2 write_string_to_stdout: mov eax,1 ; sys_write mov edi,1 mov edx,ecx syscall pop rbp rsi rbx retn display_error_string: ; in: ; esi - string ; ecx = string length, zero for ASCIIZ string ; preserves: ebx, esi push rbx rsi rbp test ecx,ecx jnz write_string_to_stderr xor al,al mov edi,esi or ecx,-1 repne scasb neg ecx sub ecx,2 write_string_to_stderr: mov eax,1 ; sys_write mov edi,2 mov edx,ecx syscall pop rbp rsi rbx retn get_environment_variable: ; in: ; esi - name ; edi - buffer for value ; ecx = size of buffer ; out: ; eax = length of value ; preserves: ebx, esi, edi push rbx rcx mov rdx,[env] scan_environment: mov rbx,[rdx] test rbx,rbx jz no_environment_variable xor ecx,ecx compare_character: mov al,[rbx+rcx] mov ah,[esi+ecx] inc ecx cmp al,'=' je end_of_variable_name test ah,ah jz next_variable sub ah,al je compare_character cmp ah,20h jne next_variable cmp al,'A' jb next_variable cmp al,'Z' jna compare_character next_variable: add rdx,8 jmp scan_environment end_of_variable_name: test ah,ah jnz next_variable add rbx,rcx pop rcx xor eax,eax copy_environment_variable: mov dl,[rbx+rax] cmp eax,ecx jae next_environment_variable_character mov [edi+eax],dl next_environment_variable_character: inc eax test dl,dl jnz copy_environment_variable environment_variable_ok: pop rbx ret no_environment_variable: pop rcx mov eax,1 jecxz environment_variable_ok and byte [edi],0 pop rbx ret VALLOC_MINIMUM_SIZE = 100000h valloc: ; in: ecx = requested minimum size ; out: eax - allocated block, ecx = allocated size, zero if failed ; preserves: ebx, esi, edi cmp ecx,VALLOC_MINIMUM_SIZE jbe valloc_size_minimum dec ecx and ecx,(-1) shl 12 add ecx,1 shl 12 jmp valloc_size_ready valloc_size_minimum: mov ecx,VALLOC_MINIMUM_SIZE valloc_size_ready: push rbx rsi rdi cmp [local_heap_available],0 je valloc_mmap cmp ecx,LOCAL_HEAP_SIZE ja valloc_mmap and [local_heap_available],0 mov eax,local_heap mov ecx,LOCAL_HEAP_SIZE jmp valloc_ok valloc_mmap: xor r9d,r9d or r8,-1 mov r10d,62h ; MAP_PRIVATE + MAP_ANONYMOUS + MAP_32BIT mov edx,3 ; PROT_READ + PROT_WRITE mov esi,ecx xor edi,edi mov eax,9 ; sys_mmap syscall cmp eax,-1 je valloc_mmap_with_hint mov ecx,eax cmp rcx,rax jne valloc_mmap_unusable add ecx,esi jnc mmap_ok valloc_mmap_unusable: mov rdi,rax mov eax,11 ; sys_munmap syscall valloc_mmap_with_hint: mov r10d,22h ; MAP_PRIVATE + MAP_ANONYMOUS mov edx,3 ; PROT_READ + PROT_WRITE mov edi,[mmap_hint] mov eax,9 ; sys_mmap syscall cmp eax,-1 je valloc_failed mov ecx,eax cmp rcx,rax jne valloc_failed add ecx,esi jc valloc_failed mmap_ok: sub ecx,eax valloc_ok: lea edx,[eax+ecx] mov [mmap_hint],edx pop rdi rsi rbx retn valloc_failed: xor ecx,ecx pop rdi rsi rbx retn