From 238069aa0d03f846f0445e369bb573fb5dbf4611 Mon Sep 17 00:00:00 2001 From: andromeda Date: Sun, 15 Mar 2026 21:18:40 +0100 Subject: [PATCH] evaluate constants as long as they are hex in the form 0x --- twasm/asm/main.asm | 76 +++++++++++++++++++++++++++++++++++++++++++++ twasm/asm/tests.asm | 68 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) diff --git a/twasm/asm/main.asm b/twasm/asm/main.asm index 8fc7b5b..5c41239 100644 --- a/twasm/asm/main.asm +++ b/twasm/asm/main.asm @@ -720,6 +720,82 @@ tokenise: .msg_operand db "operand.", 0x0A, 0x00 .pending_operator dd 0 ; the operator token that is pending processing +; ------------------------------------------------------------------------------ +; evaluate_constant +; +; description: +; takes a constant and returns its hexidecimal representation. Currently the +; following constants are supported: +; +; | type | p. | description | +; |------|----|--------------| +; | 0x00 | 0x | hexidecimal | +; | 0xFF | | unrecognised | +; +; where `p.` is the prefix +; +; parameters: +; rdi -> first byte of constant +; rsi = size of constant in bytes +; +; returned: +; rax = value of the constant in hexidecimal +; dl = type of constant; the rest of rdx is zeroed +; ------------------------------------------------------------------------------ + +evaluate_constant: + ; TODO fix this cheap trick xD + mov dl, [rdi] + 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 + + .loop: + cmp rsi, 0 ; make sure we're in range + je .break ; if not, break + + shl rax, 4 ; make room for next hex digit + + mov dl, [rdi] ; dl = next byte of constant + + sub dl, '0' ; dl = if digit: digit; else :shrug: + + cmp dl, 9 ; if !digit: + jg .alpha ; letter + jmp .continue ; else loop + + .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 + 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 + + .break: + mov rdx, 0x00 ; hex type + ret + + .unrecognised: + mov rdx, 0xFF ; unrecognised type + ret + ; ------------------------------------------------------------------------------ ; utilities ; ------------------------------------------------------------------------------ diff --git a/twasm/asm/tests.asm b/twasm/asm/tests.asm index 6fffb84..d2841b2 100644 --- a/twasm/asm/tests.asm +++ b/twasm/asm/tests.asm @@ -31,6 +31,9 @@ run_tests: call clear_test_arena call test_get_reg_bits + call clear_test_arena + call test_evaluate_constant + ret .msg db "running test suite...", 0x0A, 0x00 @@ -300,6 +303,71 @@ test_get_reg_bits: ret .msg db "test_get_reg_bits...", 0x00 +; ------------------------------------------------------------------------------ +; test_evaluate_constant +; +; description: +; tests evaluate_constant described funtionality +; ------------------------------------------------------------------------------ + +test_evaluate_constant: + mov rsi, .msg + call print.test + + ; just numerals + mov rdi, .case0 ; addr of constant + mov rsi, 8 ; length of constant + call evaluate_constant + cmp rax, [.case0_solution] + jne .fail + cmp rdx, 0x00 + jne .fail + + ; just chars + mov rdi, .case1 ; addr of constant + mov rsi, 8 ; length of constant + call evaluate_constant + cmp rax, [.case1_solution] + jne .fail + cmp rdx, 0x00 + jne .fail + + ; just chars + mov rdi, .case2 ; addr of constant + mov rsi, 12 ; length of constant + call evaluate_constant + cmp rax, [.case2_solution] + jne .fail + cmp rdx, 0x00 + jne .fail + + ; PI + mov rdi, .case3 ; addr of constant + mov rsi, 18 ; length of constant + call evaluate_constant + cmp rax, [.case3_solution] + jne .fail + cmp rdx, 0x00 + jne .fail + + .pass: + mov rsi, msg_pass + call print + ret + .fail: + mov rsi, msg_fail + 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 + msg_pass: db 0x0A times (TEST_LINE_LENGTH + .start - .end) db " ", ; right align