summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandromeda <andromeda@lenovo>2026-03-15 21:18:40 +0100
committerandromeda <andromeda@lenovo>2026-03-15 21:18:40 +0100
commit238069aa0d03f846f0445e369bb573fb5dbf4611 (patch)
tree627ca810e8416a633486c7d0d265bc3be8c458e2
parent4a3350fe4ec27bd31acbae3454449dbbf9d34584 (diff)
evaluate constants as long as they are hex in the form 0x
-rw-r--r--twasm/asm/main.asm76
-rw-r--r--twasm/asm/tests.asm68
2 files changed, 144 insertions, 0 deletions
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
@@ -721,6 +721,82 @@ tokenise:
.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