1 segment readable executable
3 macro printlen msg, len {
23 printlen msg, msg#.len
37 ;; Find the given word in the dictionary of words. If no such word exists,
41 ;; * [find.search_length] = Length of the word in bytes.
42 ;; * [find.search_buffer] = Pointer to the string containing the word.
43 ;; * rsi = Pointer to the last entry in the dictionary.
46 ;; * rsi = Pointer to the found entry in the dictionary or 0.
48 ;; Clobbers rcx, rdx, rdi, rax.
50 ;; RSI contains the entry we are currently looking at
52 movzx rcx, byte [rsi + 8 + 1] ; Length of word being looked at
53 cmp rcx, [.search_length]
54 jne .next ; If the words don't have the same length, we have the wrong word
56 ;; Otherwise, we need to compare strings
57 lea rdx, [rsi + 8 + 1 + 1] ; Location of character being compared in entry
58 mov rdi, [.search_buffer] ; Location of character being compared in search buffer
63 jne .next ; They don't match; try again
64 inc rdx ; These characters match; look at the next ones
68 jmp .found ; They match! We are done.
71 mov rsi, [rsi] ; Look at the previous entry
73 jnz .loop ; If there is no previous word, exit and return 0
78 ;; Read a word from standard input. Returns pointer to string containing word as
82 ;; * rdx = Length of string
83 ;; * rdi = Pointer to string buffer
85 ;; Clobbers pretty much everything.
88 ;; Read characters into .char_buffer until one of them is not whitespace.
95 ;; We consider newlines and spaces to be whitespace.
96 cmp [.char_buffer], ' '
98 cmp [.char_buffer], $A
102 ;; We got a character that wasn't whitespace. Now read the actual word.
106 mov al, [.char_buffer]
115 mov rsi, .char_buffer
119 cmp [.char_buffer], ' '
121 cmp [.char_buffer], $A
133 ;; * rcx = Length of string
134 ;; * rdi = Pointer to string buffer
143 ;; Add (10^(rcx-1) * parse_char(rdi[length - rcx])) to the accumulated value
147 ;; First, calcuate 10^(rcx - 1)
159 ;; Now, rax = 10^(rcx - 1).
161 ;; We need to calulate the value of the character at rdi[length - rcx].
165 movzx rbx, byte [rbx]
171 ;; Multiply this value by rax to get (10^(rcx-1) * parse_char(rdi[length - rcx])),
172 ;; then add this to the result.
175 ;; Add that value to r8
186 print parse_number.error_msg
188 printlen rdi, [.length]
192 segment readable writable
194 find.search_length dq ?
195 find.search_buffer dq ?
197 read_word.max_size = $FF
198 read_word.buffer rb read_word.max_size
199 read_word.length db ?
200 read_word.char_buffer db ?
202 parse_number.length dq ?
203 parse_number.error_msg string "Invalid number: "