; TAKEN FROM https://github.com/davidad/asm_concurrency/blob/master/os_dependent_stuff.asm ; syscalls %ifidn __OUTPUT_FORMAT__,elf64 ; http://lxr.linux.no/linux+v3.13.5/arch/x86/syscalls/syscall_64.tbl %define SYS_READ 0 %define SYS_OPEN 2 %define SYS_WRITE 1 %define SYS_MMAP 9 %define SYS_FTRUNCATE 77 %define SYS_PWRITE 18 %define SYS_FORK 57 %define SYS_WAITID 247 %define SYS_EXIT 60 %elifidn __OUTPUT_FORMAT__,macho64 ; http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/kern/syscalls.master %define SYS_READ 0x2000003 %define SYS_OPEN 0x2000005 %define SYS_WRITE 0x2000004 %define SYS_MMAP 0x20000C5 %define SYS_FTRUNCATE 0x20000C9 %define SYS_PWRITE 0x200009A %define SYS_FORK 0x2000002 %define SYS_WAITID 0x20000AD %define SYS_EXIT 0x2000001 %endif ; mmap() and mprotect() flags %ifidn __OUTPUT_FORMAT__,elf64 ; http://lxr.linux.no/linux+v3.13.5/include/uapi/asm-generic/mman-common.h %define MAP_SHARED 0x01 %define MAP_PRIVATE 0x02 %define MAP_FIXED 0x10 %define MAP_ANON 0x20 %define PROT_NONE 0x0 %define PROT_READ 0x1 %define PROT_WRITE 0x2 %define PROT_EXEC 0x4 %define PROT_SEM 0x8 %define PROT_GROWSDOWN 0x01000000 %define PROT_GROWSUP 0x02000000 %elifidn __OUTPUT_FORMAT__,macho64 ; http://www.opensource.apple.com/source/xnu/xnu-2050.18.24/bsd/sys/mman.h %define MAP_SHARED 0x001 %define MAP_PRIVATE 0x002 %define MAP_FIXED 0x010 %define MAP_RENAME 0x020 %define MAP_NORESERVE 0x040 %define MAP_INHERIT 0x080 %define MAP_NOEXTEND 0x100 %define MAP_SEMAPHORE 0x200 %define MAP_NOCACHE 0x400 %define MAP_JIT 0x800 %define MAP_FILE 0x0000 %define MAP_ANON 0x1000 %define PROT_NONE 0x0 %define PROT_READ 0x1 %define PROT_WRITE 0x2 %define PROT_EXEC 0x4 %endif %define STDIN_FILENO 0 %define STDOUT_FILENO 1 %define STDERR_FILENO 2 global start, _start, putc, putint, getc, exit, _builtin_malloc, _builtin_outofbounds default rel extern main section .text start: _start: and rsp, -16 ; make stack 16-byte aligned call main mov rdi, rax mov eax, SYS_EXIT syscall jmp $ putc: push rax push rdi push rsi push rdx push rcx push r11 mov eax, SYS_WRITE mov edi, STDOUT_FILENO lea rsi, [rsp+56] mov edx, edi syscall pop r11 pop rcx pop rdx pop rsi pop rdi pop rax ret putint: push rdi push rsi push rax push rbx push rcx push rdx push r11 mov rax, [rsp+64] mov ebx, 18 test rax, rax jz .numzero mov ecx, 10 .strlp: xor edx, edx div rcx add dl, '0' dec rbx mov [rsp+rbx], dl test rax, rax jnz .strlp jmp .strdone .numzero: dec rbx mov byte [rsp+rbx], '0' jmp .strdone .strdone: mov eax, SYS_WRITE mov edi, 1 lea rsi, [rsp+rbx] mov edx, 18 sub rdx, rbx syscall pop r11 pop rdx pop rcx pop rbx pop rax pop rsi pop rdi ret getc: push rdi push rsi push rdx push rcx push r11 mov eax, SYS_READ mov edi, STDIN_FILENO mov rsi, rsp mov edx, 1 syscall cmp rax, 1 jne .fail mov rax, [rsp] .finish: pop r11 pop rcx pop rdx pop rsi pop rdi ret .fail: mov rax, -1 jmp .finish exit: mov rdi, [rsp+8] mov eax, SYS_EXIT syscall jmp $ strlen: push rbx push rcx push rdx push rdi push rsi mov rsi, [rsp+8] ; string data pointer mov rcx, [rsi-8] ; array size xor edx, edx ; string walker cmp rcx, 16 jb .short movdqa [rsp], xmm1 movdqa [rsp-16], xmm2 mov rax, rcx ; now array size lea rbx, [rax-16] pxor xmm2, xmm2 .lp: movdqu xmm1, [rsi+rdx] pcmpistri xmm1, xmm2, 0x08 js .nullfound add rdx, 16 cmp rdx, rbx jbe .lp movdqa xmm2, [rsp-16] movdqa xmm1, [rsp] cmp rdx, rax je .nonull mov rcx, rax sub rcx, rdx .short: mov al, [rsi+rdx] inc rdx test al, al loopnz .short jnz .nonull lea rax, [rdx-1] pop rsi pop rdi pop rdx pop rcx pop rbx ret .nullfound: add rdx, rcx mov rax, rdx pop rsi pop rdi pop rdx pop rcx pop rbx ret .nonull: mov edi, STDERR_FILENO lea rsi, [nonull_msg] mov edx, nonull_msg.len mov eax, SYS_WRITE syscall jmp exit255 _builtin_malloc: push rdi push rsi push rdx push r8 push r9 push r10 push r11 push rcx xor edi, edi mov rsi, [rsp+72] mov edx, PROT_READ | PROT_WRITE mov r10d, MAP_ANON | MAP_PRIVATE mov r8d, -1 xor r9d, r9d mov eax, SYS_MMAP syscall add rax, 8 pop rcx pop r11 pop r10 pop r9 pop r8 pop rdx pop rsi pop rdi ret _builtin_outofbounds: mov edi, STDERR_FILENO lea rsi, [outofbounds_msg] mov rdx, outofbounds_msg.len mov eax, SYS_WRITE syscall exit255: mov edi, 255 mov eax, SYS_EXIT syscall jmp $ section .data outofbounds_msg: db "Runtime Error: Out-of-bounds array access detected", 10 .len: equ $ - outofbounds_msg nonull_msg: db "Runtime Error: No null byte found in string", 10 .len: equ $ - nonull_msg