From 3def806d61e248411f0c80589b36dbdc80a794fa Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sun, 2 Jan 2022 15:54:16 +0100 Subject: [PATCH] wc works really well (as char count) --- build.sh | 2 ++ src/common.asm | 43 +++++++++++++++++++++++++++++++++++++--- src/wc.asm | 53 ++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 91 insertions(+), 7 deletions(-) diff --git a/build.sh b/build.sh index 0f8b971..b2d636e 100644 --- a/build.sh +++ b/build.sh @@ -1,3 +1,5 @@ +# no, I will not use make + QUIET="false" CLEAN="false" diff --git a/src/common.asm b/src/common.asm index 7b3804c..6255094 100644 --- a/src/common.asm +++ b/src/common.asm @@ -1,5 +1,14 @@ global itoa global println_num + global open_file_arg + +WRITE_SYSCALL EQU 1 +OPEN_SYSCALL EQU 2 + +STDIN_FD EQU 0 +STDOUT_FD EQU 1 + + section .data print_num_buf: times 64 db 0 @@ -105,8 +114,36 @@ println_num: inc rbx mov rdx, rbx ; len - mov rax, 1 ; write - mov rdi, 1 ; stdout + mov rax, WRITE_SYSCALL + mov rdi, STDOUT_FD mov rsi, print_num_buf syscall - ret \ No newline at end of file + ret + + +; open_file_arg +; opens the file, stdin if it's '-' +; inputs: +; rax - filename +; outputs: +; rax - fd, <0 if there was an error +open_file_arg: + ; first, check whether the filename is - + cmp byte [rax], '-' + jne normal_filename + cmp byte [rax + 1], 0 + jne normal_filename + + ; filename is just minus + mov rax, STDIN_FD + ret + +normal_filename: + ; we have a normal file that we must open + + mov rdi, rax + mov rax, OPEN_SYSCALL + xor rsi, rsi ; no flags + xor rdx, rdx ; read-only mode + syscall + ret diff --git a/src/wc.asm b/src/wc.asm index a657a71..078ece1 100644 --- a/src/wc.asm +++ b/src/wc.asm @@ -1,25 +1,53 @@ extern itoa extern println_num + extern open_file_arg global _start IO_BUF_SIZE EQU 1024 section .data +file_not_found_msg: + db 'File not found', 10, 15 +failed_to_read_msg: + db 'Failed to read', 10, 15 io_buf: times IO_BUF_SIZE db 0 section .text _start: + pop rax ; argc + + cmp rax, 1 + je stdin_init ; if we don't have any arguments, read from stdin + + ; we do have at least one argument, open the file + pop rbx ; program name + pop rax ; filename + call open_file_arg + ; test whether there was an error + cmp rax, 0 + jl file_not_found + + mov rdi, rax + jmp init + +stdin_init: + mov rdi, 0 ; stdin + +init: + ; the input fd is in rdi at this point ; r13 is the character counter xor r13, r13 - process: mov rax, 0 - mov rdi, 0 ; stdin mov rsi, io_buf mov rdx, IO_BUF_SIZE syscall + ; test whether there was an error + cmp rax, 0 + jl failed_to_read + add r13, rax cmp rax, 0 @@ -28,7 +56,24 @@ process: count_and_print: mov rax, r13 call println_num - - mov rax, 60 xor rdi, rdi + +exit: + mov rax, 60 syscall + +failed_to_read: + mov rax, 1 ; write + mov rdi, 2 ; stderr + mov rsi, failed_to_read_msg ; buf + mov rdx, 15 ; len + jmp exit + +file_not_found: + mov rax, 1 ; write + mov rdi, 2 ; stderr + mov rsi, file_not_found_msg ; buf + mov rdx, 15 ; len + syscall + mov rdi, 1 + jmp exit