X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=impl.asm;h=a9b8564e19faeb9c6bdf3ed7b8906f1dccf7d533;hb=9e21256a9103dc92035bdef940b342522ea3efb3;hp=f8093d0653a43534971fd1a91cb590317019583b;hpb=2cd770b4f9a46cbc7ff07b26f4851bba1ea36a7d;p=rrq%2Fjonasforth.git diff --git a/impl.asm b/impl.asm index f8093d0..a9b8564 100644 --- a/impl.asm +++ b/impl.asm @@ -1,5 +1,41 @@ +;; vim: syntax=fasm + segment readable executable +macro printlen msg, len { + push rsi + add rsp, 8 + + mov rsi, msg + mov rdx, len + mov rax, 1 + mov rdi, 1 + syscall + + sub rsp, 8 + pop rsi +} + +macro newline { + push $A + printlen rsp, 1 +} + +macro print msg { + printlen msg, msg#.len +} + +macro exit code { + mov rax, $3C + mov rdi, code + syscall +} + +struc string bytes { + . db bytes + .len = $ - . +} + ;; Find the given word in the dictionary of words. If no such word exists, ;; return 0. ;; @@ -15,12 +51,12 @@ segment readable executable find: ;; RSI contains the entry we are currently looking at .loop: - movzx rcx, byte [rsi + 8] ; Length of word being looked at + movzx rcx, byte [rsi + 8 + 1] ; Length of word being looked at cmp rcx, [.search_length] jne .next ; If the words don't have the same length, we have the wrong word ;; Otherwise, we need to compare strings - lea rdx, [rsi + 8 + 1] ; Location of character being compared in entry + lea rdx, [rsi + 8 + 1 + 1] ; Location of character being compared in entry mov rdi, [.search_buffer] ; Location of character being compared in search buffer .compare_char: mov al, [rdx] @@ -96,8 +132,8 @@ read_word: ;; Parses a string. ;; ;; Parameters: -;; * [.length] = Length of string -;; * [.buffer] = Pointer to string buffer +;; * rcx = Length of string +;; * rdi = Pointer to string buffer ;; ;; Results: ;; * rax = Value @@ -108,7 +144,7 @@ parse_number: ;; Add (10^(rcx-1) * parse_char(rdi[length - rcx])) to the accumulated value ;; for each rcx. - mov rcx, [.length] + mov [.length], rcx .loop: ;; First, calcuate 10^(rcx - 1) mov rax, 1 @@ -125,12 +161,15 @@ parse_number: ;; Now, rax = 10^(rcx - 1). ;; We need to calulate the value of the character at rdi[length - rcx]. - mov rbx, rdi + mov rbx, rdi add rbx, [.length] sub rbx, rcx movzx rbx, byte [rbx] sub rbx, '0' + cmp rbx, 10 + jae .error + ;; Multiply this value by rax to get (10^(rcx-1) * parse_char(rdi[length - rcx])), ;; then add this to the result. mul rbx @@ -144,6 +183,13 @@ parse_number: mov rax, r8 ret +.error: + push rdi + print parse_number.error_msg + pop rdi + printlen rdi, [.length] + newline + exit 100 segment readable writable @@ -155,6 +201,6 @@ read_word.buffer rb read_word.max_size read_word.length db ? read_word.char_buffer db ? -parse_number.buffer dq ? parse_number.length dq ? +parse_number.error_msg string "Invalid number: "