From c05adee382fec7b28a971cc6460d81e486bd3684 Mon Sep 17 00:00:00 2001 From: andromeda Date: Sun, 15 Mar 2026 21:55:16 +0100 Subject: [PATCH] add octal --- twasm/asm/main.asm | 64 ++++++++++++++++++++++++++++++++++----------- twasm/asm/tests.asm | 52 ++++++++++++++++++++++-------------- 2 files changed, 81 insertions(+), 35 deletions(-) diff --git a/twasm/asm/main.asm b/twasm/asm/main.asm index 5c41239..069e3f3 100644 --- a/twasm/asm/main.asm +++ b/twasm/asm/main.asm @@ -626,7 +626,7 @@ tokenise: jmp .operator_id_loop - .found_id + .found_id: push rdx mov dx, [rcx + 4] ; dx = token id @@ -730,6 +730,7 @@ tokenise: ; | type | p. | description | ; |------|----|--------------| ; | 0x00 | 0x | hexidecimal | +; | 0x01 | 0b | octal | ; | 0xFF | | unrecognised | ; ; where `p.` is the prefix @@ -744,24 +745,38 @@ tokenise: ; ------------------------------------------------------------------------------ evaluate_constant: + ; rsi = number of bytes left + ; rdi -> current byte of constant + xor eax, eax ; rax = value of constant + ; TODO fix this cheap trick xD mov dl, [rdi] + dec rsi ; one fewer byte left + inc rdi ; point to next byte cmp dl, '0' jne .unrecognised - dec rsi ; one fewer byte left - inc rdi ; point to next byte mov dl, [rdi] - cmp dl, 'x' - jne .unrecognised dec rsi ; one fewer byte left inc rdi ; point to next byte - ; rsi = number of bytes left - ; rdi -> current byte of constant - xor eax, eax ; rax = value in hex of constant + ; hex case + mov rcx, 0x00 + push rcx + cmp dl, 'x' + je .hex_loop + pop rcx - .loop: + ; octal case + mov rcx, 0x01 + push rcx + cmp dl, 'q' + je .oct_loop + pop rcx + + jmp .unrecognised + + .hex_loop: cmp rsi, 0 ; make sure we're in range je .break ; if not, break @@ -772,24 +787,43 @@ evaluate_constant: sub dl, '0' ; dl = if digit: digit; else :shrug: cmp dl, 9 ; if !digit: - jg .alpha ; letter - jmp .continue ; else loop + jg .hex_alpha ; letter + jmp .hex_continue ; else loop - .alpha + .hex_alpha: sub dl, 7 ; map [('A'-'0')..('F'-'0')] to [0xA..0xF] cmp dl, 0xF ; if not in the range [0xA..0xF] jg .unrecognised ; then unrecognised - .continue + .hex_continue: and dl, 0x0F ; mask or al, dl ; and add newest nibble dec rsi ; one fewer byte left inc rdi ; point to next byte - jmp .loop ; and loop + jmp .hex_loop ; and loop + + .oct_loop: + cmp rsi, 0 ; make sure we're in range + je .break ; if not, break + + shl rax, 3 ; make room for next octal digit + + mov dl, [rdi] ; dl = next byte of constant + + sub dl, '0' + cmp dl, 7 + jg .unrecognised + + and dl, 7 ; mask + or al, dl ; and add newest 3-bit group + + dec rsi ; one fewer byte left + inc rdi ; point to next byte + jmp .oct_loop ; and loop .break: - mov rdx, 0x00 ; hex type + pop rdx ret .unrecognised: diff --git a/twasm/asm/tests.asm b/twasm/asm/tests.asm index 190f4c2..10c80ad 100644 --- a/twasm/asm/tests.asm +++ b/twasm/asm/tests.asm @@ -315,41 +315,50 @@ test_evaluate_constant: call print.test ; just numerals - mov rdi, .case0 ; addr of constant - mov rsi, 8 ; length of constant + mov rdi, .case0h ; addr of constant + mov rsi, 8 ; length of constant call evaluate_constant - cmp rax, [.case0_solution] + cmp rax, [.case0h_solution] jne .fail cmp rdx, 0x00 jne .fail ; just chars - mov rdi, .case1 ; addr of constant - mov rsi, 8 ; length of constant + mov rdi, .case1h ; addr of constant + mov rsi, 8 ; length of constant call evaluate_constant - cmp rax, [.case1_solution] + cmp rax, [.case1h_solution] jne .fail cmp rdx, 0x00 jne .fail ; just chars - mov rdi, .case2 ; addr of constant - mov rsi, 12 ; length of constant + mov rdi, .case2h ; addr of constant + mov rsi, 12 ; length of constant call evaluate_constant - cmp rax, [.case2_solution] + cmp rax, [.case2h_solution] jne .fail cmp rdx, 0x00 jne .fail ; PI - mov rdi, .case3 ; addr of constant - mov rsi, 18 ; length of constant + mov rdi, .case3h ; addr of constant + mov rsi, 18 ; length of constant call evaluate_constant - cmp rax, [.case3_solution] + cmp rax, [.case3h_solution] jne .fail cmp rdx, 0x00 jne .fail + ; PI + mov rdi, .case0q + mov rsi, 16 + call evaluate_constant + cmp rax, [.case0q_solution] + jne .fail + cmp rdx, 0x01 + jne .fail + .pass: mov rsi, msg_pass call print @@ -359,14 +368,17 @@ test_evaluate_constant: call print ret .msg db "test_evaluate_constant...", 0x00 - .case0 db "0x012390" - .case0_solution dq 0x012390 - .case1 db "0xABCDEF" - .case1_solution dq 0xABCDEF - .case2 db "0x1234567890" - .case2_solution dq 0x1234567890 - .case3 db "0x243F6A8885A308D3" - .case3_solution dq 0x243F6A8885A308D3 + .case0h db "0x012390" + .case0h_solution dq 0x012390 + .case1h db "0xABCDEF" + .case1h_solution dq 0xABCDEF + .case2h db "0x1234567890" + .case2h_solution dq 0x1234567890 + .case3h db "0x243F6A8885A308D3" + .case3h_solution dq 0x243F6A8885A308D3 + + .case0q db "0q31103755242102" + .case0q_solution dq 0q31103755242102 msg_pass: db 0x0A