From f7f5ae6f96b41d70d24cf0a4670164aadb73813f Mon Sep 17 00:00:00 2001 From: Tijmen van Nesselrooij Date: Mon, 5 Aug 2019 20:39:46 +0200 Subject: [PATCH] Added collatz homework assignment --- x86_64/4_collatz.asm | 125 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 x86_64/4_collatz.asm diff --git a/x86_64/4_collatz.asm b/x86_64/4_collatz.asm new file mode 100644 index 0000000..8d4a614 --- /dev/null +++ b/x86_64/4_collatz.asm @@ -0,0 +1,125 @@ +global _start + +section .bss + NR_INPUT_BUFFER: resb 4 + NR_INPUT_BUFFER_SIZE: equ 4 + +section .data + RQ_NR_STR: db 'Please give me a number (0-999): ' + RQ_NR_STR_SIZE: equ $ - RQ_NR_STR + + NR_STR: db '8' + NR_STR_SIZE: equ 1 + + ZERO_ASCII_VALUE: equ 48 + NINE_ASCII_VALUE: equ 57 + INPUT_BASE: equ 10 + + STDOUT: equ 1 + +section .text +_start: + ; Write to STDOUT + mov rax, 1 ; = write + mov rdi, STDOUT + mov rsi, RQ_NR_STR + mov rdx, RQ_NR_STR_SIZE + syscall + + ; Read from STDIN + xor rax, rax ; 0 = read + xor rdi, rdi ; 0 = stdin + mov rsi, NR_INPUT_BUFFER + mov rdx, NR_INPUT_BUFFER_SIZE + syscall + + ; Parse number + mov rdi, NR_INPUT_BUFFER ; array to loop + dec rax + mov rsi, rax ; loop limit + call parseNR + + mov rdi, rax + call collatz + + mov rdi, rax +exit: + mov rax, 60 + syscall + +; int ParseNumber(char * p, size_t length) +; IN +; - rdi = ptr to byte array +; - rsi = length of said array (greater than 0) +; OUT +; - rax = resulting number => returns 0 if it cannot parse +parseNR: + xor r8, r8 ; loop variable + xor rcx, rcx ; sum +.loop_body: + mov rax, rcx + mov rcx, qword INPUT_BASE + mul rcx + mov rcx, rax + + movzx rax, byte [rdi + r8] + ; Check if the value is within ASCII numeric bounds + cmp al, byte ZERO_ASCII_VALUE + jb .exit_failure + cmp al, byte NINE_ASCII_VALUE + jnb .exit_failure + + ; Subtract zero to make it a number + sub al, byte ZERO_ASCII_VALUE + + ; Store the sum + add rcx, rax + + inc r8 + + cmp r8, rsi + jb .loop_body + + ; Return the result + mov rax, rcx + jmp .exit + +.exit_failure: + xor rax, rax +.exit: + ret + +; int Collatz(int n) +; IN +; - rdi = number to "collatz" +; OUT +; - rax = number of "collatz" iterations it took to reach 0 +collatz: + xor r9, r9 ; iteration count + +.loop_start: + cmp rdi, qword 1 + jbe .loop_exit + + inc r9 + + ; Is rdi odd? + mov rax, rdi + and rax, qword 1 + cmp rax, qword 1 + je .uneven_routine + +;.even_routine: + shr rdi, 1 ; divide by two using right shift 1 + jmp .loop_start + +.uneven_routine: + mov rax, rdi + add rdi, rdi ; rdi + rdi + add rdi, rax ; rdi + rdi + rdi = 3 * rdi + inc rdi + jmp .loop_start + +.loop_exit: + mov rax, r9 + ret \ No newline at end of file