X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=impl.asm;h=ea6c04ebd42155a2dd5f495ac57874308ad2fbe4;hb=55d4cc10bbfa7bc445948b222b6a72d2d4b127a2;hp=a9b8564e19faeb9c6bdf3ed7b8906f1dccf7d533;hpb=4061939a8f1a4afd749434ed70a6122016c0a8dc;p=rrq%2Fjonasforth.git diff --git a/impl.asm b/impl.asm index a9b8564..ea6c04e 100644 --- a/impl.asm +++ b/impl.asm @@ -1,16 +1,14 @@ ;; vim: syntax=fasm -segment readable executable +section '.text' code readable executable macro printlen msg, len { push rsi add rsp, 8 - mov rsi, msg + mov rcx, msg mov rdx, len - mov rax, 1 - mov rdi, 1 - syscall + sys_print_string sub rsp, 8 pop rsi @@ -25,12 +23,6 @@ macro print msg { printlen msg, msg#.len } -macro exit code { - mov rax, $3C - mov rdi, code - syscall -} - struc string bytes { . db bytes .len = $ - . @@ -88,11 +80,8 @@ find: read_word: .skip_whitespace: ;; Read characters into .char_buffer until one of them is not whitespace. - mov rax, 0 - mov rdi, 0 mov rsi, .char_buffer - mov rdx, 1 - syscall + sys_read_char ;; We consider newlines and spaces to be whitespace. cmp [.char_buffer], ' ' @@ -112,11 +101,8 @@ read_word: mov [rsi], al inc [.length] - mov rax, 0 - mov rdi, 0 mov rsi, .char_buffer - mov rdx, 1 - syscall + sys_read_char cmp [.char_buffer], ' ' je .end @@ -129,6 +115,60 @@ read_word: ret +;; Read a word from a buffer. Returns the buffer without the word, as well as +;; the word that was read (including lengths). +;; +;; Inputs: +;; * rsi = Input buffer +;; * rcx = Length of buffer +;; +;; Outputs: +;; * rsi = Updated buffer +;; * rcx = Length of updated buffer +;; * rdi = Word buffer +;; * rdx = Length of word buffer +pop_word: +.skip_whitespace: + mov al, [rsi] + cmp al, ' ' + je .got_whitespace + cmp al, $A + je .got_whitespace + jmp .alpha +.got_whitespace: + ;; The buffer starts with whitespace; discard the first character from the buffer. + inc rsi + dec rcx + jmp .skip_whitespace + +.alpha: + ;; We got a character that wasn't whitespace. Now read the actual word. + mov rdi, rsi ; This is where the word starts + mov rdx, 1 ; Length of word + +.read_alpha: + ;; Extract character from original buffer: + inc rsi + dec rcx + + ;; When we hit whitespace, we are done with this word + mov al, [rsi] + cmp al, ' ' + je .end + cmp al, $A + je .end + + ;; It wasn't whitespace; add it to word buffer + inc rdx + jmp .read_alpha + +.end: + ;; Finally, we want to skip one whitespace character after the word. + inc rsi + dec rcx + + ret + ;; Parses a string. ;; ;; Parameters: @@ -189,9 +229,9 @@ parse_number: pop rdi printlen rdi, [.length] newline - exit 100 + sys_terminate 100 -segment readable writable +section '.data' readable writable find.search_length dq ? find.search_buffer dq ?