diff --git a/twasm/.bootle/disk b/twasm/.bootle/disk new file mode 100644 index 0000000..995de23 Binary files /dev/null and b/twasm/.bootle/disk differ diff --git a/twasm/asm/main.asm b/twasm/asm/main.asm index 4b23759..8b2d7ef 100644 --- a/twasm/asm/main.asm +++ b/twasm/asm/main.asm @@ -578,8 +578,8 @@ tokenise: pop rsi push rax - mov dword [.pending_operator], 0 ; zero pending operator - xor eax, eax ; eax = number of bytes in operator + xor eax, eax ; eax = number of bytes in operator + mov [.pending_operator], eax ; zero pending operator .operator_loop: ; TODO give this its own error @@ -606,35 +606,19 @@ tokenise: jmp .operator_loop ; and loop .operator_break: - pop rax + ; rax already pushed from .operator + push rdi - push rcx - mov rcx, tokens.operators ; rcx -> entry in lookup table + mov edi, [.pending_operator] ; edi = operator to be searched + call identify_operator + ; ax = operator's token ID + mov cx, ax ; cx = operator's token ID for safe keeping - .operator_id_loop: - cmp rcx, tokens.operators_end ; check if index still in range - ; TODO give own error - jg .unexpected_operator ; if not, error + pop rdi ; rdi = byte counter + pop rax ; rax = tokens processed - ; TODO use something other than r8 and r9 - mov r8d, [rcx] - mov r9d, [.pending_operator] - cmp r8d, r9d - je .found_id - - add rcx, 6 ; next entry - - jmp .operator_id_loop - - .found_id: - push rdx - mov dx, [rcx + 4] ; dx = token id - - mov [TOKEN_TABLE_ADDR + rax * TOKEN_TABLE_ENTRY_SIZE], dx ; write to token - inc rax ; table - - pop rdx - pop rcx + mov [TOKEN_TABLE_ADDR + rax * TOKEN_TABLE_ENTRY_SIZE], cx + inc rax ; plus 1 token processed mov byte [.expecting], E_COMMENT | E_NEWLINE | E_WHITESPACE | E_OPERAND jmp .loop @@ -650,6 +634,7 @@ tokenise: test byte [.expecting], E_OPERAND ; make sure an operand was expected jz .unexpected_operand ; if not, error + .operand_loop: mov dl, [rdi] @@ -720,6 +705,67 @@ tokenise: .msg_operand db "operand.", 0x0A, 0x00 .pending_operator dd 0 ; the operator token that is pending processing +; ------------------------------------------------------------------------------ +; evaluate_operand +; +; description: +; takes the location and length of an operand and evaluates it into binary data +; and a return code to interpret the binary data. +; +; | code | rsi contents | notes | +; |------|----------------------|-------| +; | 0x00 | token ID of register | | +; | 0xFF | - | error | +; +; parameters: +; rdi -> first byte of operand +; rsi = size of operand in bytes +; +; returned: +; rax = binary data corresponding to the operand +; dl = return code +; ------------------------------------------------------------------------------ + +evaluate_operand: + cmp rsi, 4 + jg .unrecognised + + .register: + push rdi + mov edi, [rdi] ; edi = register to be searched + + ; TODO figure out how to mask elegantly :/ + ; mask edi for lower rsi bits + cmp rsi, 4 + je .register4 + cmp rsi, 3 + je .register3 + cmp rsi, 2 + je .register2 + cmp rsi, 1 + je .register1 + .register1: + and edi, 0xFF + .register2: + and edi, 0xFFFF + .register3: + and edi, 0xFFFFFF + .register4: + + call identify_register + ; ax = register's token ID or UNRECOGNISED_TOKEN_ID + pop rdi + + cmp ax, UNRECOGNISED_TOKEN_ID + je .unrecognised + + mov dl, 0x00 + ret + + .unrecognised: + mov dl, 0xFF + ret + ; ------------------------------------------------------------------------------ ; evaluate_constant ; diff --git a/twasm/asm/tests.asm b/twasm/asm/tests.asm index b7a9bec..e2dd79e 100644 --- a/twasm/asm/tests.asm +++ b/twasm/asm/tests.asm @@ -40,6 +40,9 @@ run_tests: call clear_test_arena call test_identify_operator + call clear_test_arena + call test_evaluate_operand + ret .msg db "running test suite...", 0x0A, 0x00 @@ -499,6 +502,52 @@ test_identify_operator: ret .msg db "test_identify_operator...", 0x00 +; ------------------------------------------------------------------------------ +; test_evaluate_operand +; +; description: +; tests evaluate_operand described funtionality +; ------------------------------------------------------------------------------ + +test_evaluate_operand: + mov rsi, .msg + call print.test + + mov rdi, .case0 + mov rsi, 3 + call evaluate_operand + cmp dl, 0x00 + jne .fail + cmp ax, 0x0000 + jne .fail + + mov rdi, .case1 + mov rsi, 0 + call evaluate_operand + cmp dl, 0xFF + jne .fail + + mov rdi, .case2 + mov rsi, 3 + call evaluate_operand + cmp dl, 0x00 + jne .fail + cmp ax, 0x0003 + jne .fail + + .pass: + mov rsi, msg_pass + call print + ret + .fail: + mov rsi, msg_fail + call print + ret + .case0 db "rax" + .case1: ; intentionally blank + .case2 db "rdx" + .msg db "test_evaluate_operand...", 0x00 + msg_pass: db 0x0A times (TEST_LINE_LENGTH + .start - .end) db " ", ; right align