diff --git a/a.out b/a.out index 9c30d5e..b6e3423 100755 Binary files a/a.out and b/a.out differ diff --git a/build/a.asm b/build/a.asm index bf532f2..2cc2435 100644 --- a/build/a.asm +++ b/build/a.asm @@ -18,17 +18,30 @@ _start: mov rdi, rax mov rax, 60 syscall +word_c_40: + mov rax, [r12] + movzx rax, byte [rax] + mov [r12], rax + ret + ret +word_c_21: + mov rax, [r12] + add r12, 8 + mov rbx, [r12] + mov [rbx], al + ret + ret +word_r_40: + mov rax, [r13] + sub r12, 8 + mov [r12], rax + ret + ret word_strlen: - mov rsi, [r12] ; addr - mov rcx, 0 -strlen_loop: - mov al, [rsi + rcx] - cmp al, 0 - je strlen_done - inc rcx - jmp strlen_loop -strlen_done: - mov [r12], rcx ; len + mov rax, [r12] ; addr + mov rcx, [r12 + 8] ; len + add r12, 16 ; pop len and addr + mov [r12], rcx ; push len ret ret word_puts: @@ -113,6 +126,15 @@ word_dup: sub r12, 8 mov [r12], rax ret +word_write_buf: + mov rdx, [r12] ; len + mov rsi, [r12 + 8] ; addr + add r12, 16 ; pop len + addr + mov rax, 1 ; syscall: write + mov rdi, 1 ; fd = stdout + syscall + ret + ret word_drop: add r12, 8 ret @@ -284,20 +306,22 @@ word__21: add r12, 8 ret word_mmap: - mov r9, [r12] - add r12, 8 - mov r8, [r12] - add r12, 8 - mov r10, [r12] - add r12, 8 - mov rdx, [r12] - add r12, 8 - mov rsi, [r12] - add r12, 8 - mov rdi, [r12] - mov rax, 9 - syscall - mov [r12], rax + ; Save rsp and align to 16 bytes for syscall ABI + mov rax, rsp + and rsp, -16 + mov rdi, [r12+40] ; addr + mov rsi, [r12+32] ; length + mov rdx, [r12+24] ; prot + mov r10, [r12+16] ; flags + mov r8, [r12+8] ; fd + mov r9, [r12] ; offset + add r12, 48 ; pop 6 args + mov rax, 9 ; syscall: mmap + syscall + mov rsp, rax ; restore rsp + sub r12, 8 + mov [r12], rax ; push result + ret ret word_munmap: mov rsi, [r12] diff --git a/build/a.o b/build/a.o index 6e22e17..f77941f 100644 Binary files a/build/a.o and b/build/a.o differ diff --git a/build/hello.asm b/build/hello.asm index 12c9dff..2cc2435 100644 --- a/build/hello.asm +++ b/build/hello.asm @@ -18,6 +18,32 @@ _start: mov rdi, rax mov rax, 60 syscall +word_c_40: + mov rax, [r12] + movzx rax, byte [rax] + mov [r12], rax + ret + ret +word_c_21: + mov rax, [r12] + add r12, 8 + mov rbx, [r12] + mov [rbx], al + ret + ret +word_r_40: + mov rax, [r13] + sub r12, 8 + mov [r12], rax + ret + ret +word_strlen: + mov rax, [r12] ; addr + mov rcx, [r12 + 8] ; len + add r12, 16 ; pop len and addr + mov [r12], rcx ; push len + ret + ret word_puts: ; detects string if top is len>=0 and next is a pointer in [data_start, data_end] mov rax, [r12] ; len or int value @@ -100,6 +126,15 @@ word_dup: sub r12, 8 mov [r12], rax ret +word_write_buf: + mov rdx, [r12] ; len + mov rsi, [r12 + 8] ; addr + add r12, 16 ; pop len + addr + mov rax, 1 ; syscall: write + mov rdi, 1 ; fd = stdout + syscall + ret + ret word_drop: add r12, 8 ret @@ -271,20 +306,22 @@ word__21: add r12, 8 ret word_mmap: - mov r9, [r12] - add r12, 8 - mov r8, [r12] - add r12, 8 - mov r10, [r12] - add r12, 8 - mov rdx, [r12] - add r12, 8 - mov rsi, [r12] - add r12, 8 - mov rdi, [r12] - mov rax, 9 - syscall - mov [r12], rax + ; Save rsp and align to 16 bytes for syscall ABI + mov rax, rsp + and rsp, -16 + mov rdi, [r12+40] ; addr + mov rsi, [r12+32] ; length + mov rdx, [r12+24] ; prot + mov r10, [r12+16] ; flags + mov r8, [r12+8] ; fd + mov r9, [r12] ; offset + add r12, 48 ; pop 6 args + mov rax, 9 ; syscall: mmap + syscall + mov rsp, rax ; restore rsp + sub r12, 8 + mov [r12], rax ; push result + ret ret word_munmap: mov rsi, [r12] diff --git a/build/hello.o b/build/hello.o index 5ba708d..e3e581a 100644 Binary files a/build/hello.o and b/build/hello.o differ diff --git a/build/main.asm b/build/main.asm index e644000..0305d97 100644 --- a/build/main.asm +++ b/build/main.asm @@ -18,6 +18,32 @@ _start: mov rdi, rax mov rax, 60 syscall +word_c_40: + mov rax, [r12] + movzx rax, byte [rax] + mov [r12], rax + ret + ret +word_c_21: + mov rax, [r12] + add r12, 8 + mov rbx, [r12] + mov [rbx], al + ret + ret +word_r_40: + mov rax, [r13] + sub r12, 8 + mov [r12], rax + ret + ret +word_strlen: + mov rax, [r12] ; addr + mov rcx, [r12 + 8] ; len + add r12, 16 ; pop len and addr + mov [r12], rcx ; push len + ret + ret word_puts: ; detects string if top is len>=0 and next is a pointer in [data_start, data_end] mov rax, [r12] ; len or int value @@ -100,6 +126,15 @@ word_dup: sub r12, 8 mov [r12], rax ret +word_write_buf: + mov rdx, [r12] ; len + mov rsi, [r12 + 8] ; addr + add r12, 16 ; pop len + addr + mov rax, 1 ; syscall: write + mov rdi, 1 ; fd = stdout + syscall + ret + ret word_drop: add r12, 8 ret @@ -271,20 +306,22 @@ word__21: add r12, 8 ret word_mmap: - mov r9, [r12] - add r12, 8 - mov r8, [r12] - add r12, 8 - mov r10, [r12] - add r12, 8 - mov rdx, [r12] - add r12, 8 - mov rsi, [r12] - add r12, 8 - mov rdi, [r12] - mov rax, 9 - syscall - mov [r12], rax + ; Save rsp and align to 16 bytes for syscall ABI + mov rax, rsp + and rsp, -16 + mov rdi, [r12+40] ; addr + mov rsi, [r12+32] ; length + mov rdx, [r12+24] ; prot + mov r10, [r12+16] ; flags + mov r8, [r12+8] ; fd + mov r9, [r12] ; offset + add r12, 48 ; pop 6 args + mov rax, 9 ; syscall: mmap + syscall + mov rsp, rax ; restore rsp + sub r12, 8 + mov [r12], rax ; push result + ret ret word_munmap: mov rsi, [r12] diff --git a/build/main.o b/build/main.o index 5f778c4..e49159b 100644 Binary files a/build/main.o and b/build/main.o differ diff --git a/build/str.asm b/build/str.asm index aba2433..096670b 100644 --- a/build/str.asm +++ b/build/str.asm @@ -472,7 +472,57 @@ word_read_file: mov qword [r12 + 8], -3 ret ret -word_main: +word_write_file: + ; stack: path_ptr (top), path_len, buf_ptr, buf_len + mov rsi, [r12] ; path_ptr + mov rdx, [r12 + 8] ; path_len + mov r15, [r12 + 16] ; buf_ptr (save in callee-saved r15) + mov r13, [r12 + 24] ; buf_len (save in callee-saved r13) + add r12, 32 ; pop 4 args (we saved buf info) + + ; open(path_ptr, O_WRONLY|O_CREAT|O_TRUNC, 0666) + mov rdi, rsi ; filename + mov rsi, 577 ; flags = O_WRONLY|O_CREAT|O_TRUNC + mov rdx, 438 ; mode = 0o666 + mov rax, 2 ; syscall: open + syscall + cmp rax, 0 + jl .fail_open + mov r9, rax ; save fd + + ; write(fd, buf_ptr, buf_len) -- use preserved r15/r13 which survive syscalls + mov rax, 1 ; syscall: write + mov rdi, r9 ; fd + mov rsi, r15 ; buf_ptr + mov rdx, r13 ; buf_len + syscall + mov r10, rax ; save write result + cmp r10, 0 + jl .fail_write + + ; close(fd) + mov rax, 3 ; syscall: close + mov rdi, r9 + syscall + + sub r12, 8 + mov [r12], r10 + ret + +.fail_write: + mov rax, 3 + mov rdi, r9 + syscall + sub r12, 8 + mov [r12], r10 + ret + +.fail_open: + sub r12, 8 + mov [r12], rax + ret + ret +word_main2: ; push str_0 sub r12, 8 mov qword [r12], str_0 @@ -486,10 +536,22 @@ word_main: sub r12, 8 mov qword [r12], 0 ret +word_main: + ; push str_1 + sub r12, 8 + mov qword [r12], str_1 + ; push 7 + sub r12, 8 + mov qword [r12], 7 + call word_dup + call word_puts + ret section .data data_start: str_0: db 115, 116, 114, 46, 115, 108, 0 str_0_len equ 6 +str_1: db 118, 99, 120, 122, 118, 103, 103, 0 +str_1_len equ 7 data_end: section .bss align 16 diff --git a/build/str.o b/build/str.o index 5c58829..64e6be2 100644 Binary files a/build/str.o and b/build/str.o differ diff --git a/build/test_write_file.asm b/build/test_write_file.asm index 841bc91..a4fb632 100644 --- a/build/test_write_file.asm +++ b/build/test_write_file.asm @@ -526,18 +526,17 @@ word_main: ; push str_0 sub r12, 8 mov qword [r12], str_0 - ; push 22 - sub r12, 8 - mov qword [r12], 22 - call word_swap - ; push str_1 - sub r12, 8 - mov qword [r12], str_1 ; push 27 sub r12, 8 mov qword [r12], 27 call word_swap - call word_2swap + ; push str_1 + sub r12, 8 + mov qword [r12], str_1 + ; push 22 + sub r12, 8 + mov qword [r12], 22 + call word_swap call word_write_file call word_dup ; push 0 @@ -573,10 +572,10 @@ L_if_false_0: ret section .data data_start: -str_0: db 47, 116, 109, 112, 47, 108, 50, 95, 116, 101, 115, 116, 95, 119, 114, 105, 116, 101, 46, 116, 120, 116, 0 -str_0_len equ 22 -str_1: db 104, 101, 108, 108, 111, 32, 102, 114, 111, 109, 32, 119, 114, 105, 116, 101, 95, 102, 105, 108, 101, 32, 116, 101, 115, 116, 10, 0 -str_1_len equ 27 +str_0: db 104, 101, 108, 108, 111, 32, 102, 114, 111, 109, 32, 119, 114, 105, 116, 101, 95, 102, 105, 108, 101, 32, 116, 101, 115, 116, 10, 0 +str_0_len equ 27 +str_1: db 47, 116, 109, 112, 47, 108, 50, 95, 116, 101, 115, 116, 95, 119, 114, 105, 116, 101, 46, 116, 120, 116, 0 +str_1_len equ 22 str_2: db 119, 114, 111, 116, 101, 32, 98, 121, 116, 101, 115, 58, 32, 0 str_2_len equ 13 str_3: db 119, 114, 105, 116, 101, 32, 102, 97, 105, 108, 101, 100, 32, 101, 114, 114, 110, 111, 61, 0 diff --git a/build/test_write_file.o b/build/test_write_file.o index b6082c5..1851e6d 100644 Binary files a/build/test_write_file.o and b/build/test_write_file.o differ diff --git a/stdlib/stdlib.sl b/stdlib/stdlib.sl index 37d4e7f..e39df4c 100644 --- a/stdlib/stdlib.sl +++ b/stdlib/stdlib.sl @@ -26,16 +26,6 @@ } ; -# : strlen ( addr len -- len ) -:asm strlen { - mov rax, [r12] ; addr - mov rcx, [r12 + 8] ; len - add r12, 16 ; pop len and addr - mov [r12], rcx ; push len - ret -} -; - :asm puts { ; detects string if top is len>=0 and next is a pointer in [data_start, data_end] mov rax, [r12] ; len or int value diff --git a/test_write_file.sl b/test_write_file.sl index 002f8f4..7e1c29a 100644 --- a/test_write_file.sl +++ b/test_write_file.sl @@ -2,11 +2,10 @@ import stdlib/stdlib.sl import stdlib/io.sl : main - "/tmp/l2_test_write.txt" # push path (len addr) - swap # -> (addr len) = path_ptr path_len "hello from write_file test\n" # push buf (len addr) swap # -> (addr len) = buf_ptr buf_len - 2swap # reorder pairs -> path_ptr path_len buf_ptr buf_len + "/tmp/l2_test_write.txt" # push path (len addr) + swap # -> (addr len) = path_ptr path_len write_file dup 0 > if "wrote bytes: " puts diff --git a/write b/write index 7daac9d..ec3c604 100755 Binary files a/write and b/write differ