From ad9be1029c55ccc0805b1bee08f1058bbbe869b6 Mon Sep 17 00:00:00 2001 From: andromeda Date: Tue, 31 Mar 2026 21:05:41 +0200 Subject: [PATCH] start w labels idk --- twasm/asm/main.asm | 224 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 210 insertions(+), 14 deletions(-) diff --git a/twasm/asm/main.asm b/twasm/asm/main.asm index 1666336..6310bbc 100644 --- a/twasm/asm/main.asm +++ b/twasm/asm/main.asm @@ -51,7 +51,7 @@ start: call clear_token_table call clear_label_tables - mov rdi, program ; -> program + mov rdi, program ; -> program mov rsi, [program.size] ; = size of program call tokenise ; rax = number of tokens in token table @@ -99,16 +99,26 @@ assemble: .loop: call .flush_write_buffer call .get_next_tte - ; di = tte + push rdi ; di = tte call get_tte_type - ; al = type + ; al = type + pop rdi ; di = tte cmp al, 0x1 ; check if next tte is an operator je .operator ; if so, handle + cmp al, 0x4 ; check if next tte is a label + je .label + jmp .unexpected_token ; otherwise, fail - .operator: ; if next tte's type is an operator: + .label: + push rsi + mov rsi, .msg_label + call print.debug + pop rsi + jmp .loop_next_token + .operator: ; di = tte of operator call get_tte_typed_metadata ; al = tte typed metadata @@ -129,8 +139,10 @@ assemble: jmp .unexpected_token .operator_0: + push rsi mov rsi, .msg_operator_0 call print.debug + pop rsi ; di = tte of operator mov sil, 0b ; opcode @@ -141,8 +153,10 @@ assemble: jmp .loop_next_token .operator_1: + push rsi mov rsi, .msg_operator_1 call print.debug + pop rsi ; di = tte of operator mov sil, 0b ; dst=r/m @@ -174,12 +188,16 @@ assemble: jmp .unexpected_token .operator_1_memory: + push rsi mov rsi, .msg_operator_1_memory call print.debug + pop rsi jmp .unsupported_memory_access .operator_1_register: + push rsi mov rsi, .msg_operator_1_register call print.debug + pop rsi ; di = token table entry call get_tte_typed_metadata @@ -218,8 +236,10 @@ assemble: jmp .loop_next_token .operator_2: + push rsi mov rsi, .msg_operator_2 call print.debug + pop rsi mov cx, di ; cx = tte of operator @@ -244,8 +264,10 @@ assemble: jmp .unexpected_token .operator_2_memory: + push rsi mov rsi, .msg_operator_2_memory call print.debug + pop rsi cmp di, 0x1000 ; check if token is addressing a register jne .unsupported_memory_access ; if not, unsupported @@ -339,22 +361,16 @@ assemble: jmp .loop_next_token .operator_2_register: + push rsi mov rsi, .msg_operator_2_register call print.debug + pop rsi - push rdi - mov di, cx ; di = tte of operator - mov sil, 1 ; dst = reg - call get_opcode - ; al = opcode - ; dl = op flag - ; TODO do something if the op flag is present - call .write_byte - pop rdi ; di = dst tte - + push rcx ; di = token table entry call get_tte_typed_metadata ; al = register typed metadata + pop rcx ; cx = operator tte and al, 11b ; al = register width @@ -390,6 +406,12 @@ assemble: pop rdi ; di = next tte je .operator_2_register_memory + push rdi + and di, 0xFF00 + cmp di, 0x2000 ; check if token is a constant + pop rdi ; di = next tte + je .operator_2_register_const + ; di = next tte call get_tte_type ; al = type of token @@ -404,6 +426,18 @@ assemble: call print.debug pop rsi ; si = dst tte + push rdi + push rsi + mov di, cx ; di = tte of operator + mov sil, 1 ; dst = reg + call get_opcode + ; al = opcode + ; dl = op flag + ; TODO do something if the op flag is present + call .write_byte + pop rsi ; si = tte + pop rdi ; di = tte + cmp di, 0x1000 ; check if token is addressing to a register jne .unsupported_memory_access ; if not, unsupported @@ -446,6 +480,18 @@ assemble: call print.debug pop rsi ; si = dst tte + push rdi + push rsi + mov di, cx ; di = tte of operator + mov sil, 1 ; dst = reg + call get_opcode + ; al = opcode + ; dl = op flag + ; TODO do something if the op flag is present + call .write_byte + pop rsi ; si = tte + pop rdi ; di = tte + ; di = tte call get_tte_typed_metadata ; al = register typed metadata @@ -550,6 +596,82 @@ assemble: call .write_byte jmp .loop_next_token + .operator_2_register_const: + push rsi + mov rsi, .msg_operator_2_register_const + call print.debug + pop rsi ; si = dst tte + + push rdi + push rsi + mov di, cx ; di = tte of operator + mov sil, 2 ; dst=r/m,src=imm + call get_opcode + ; al = opcode + ; dl = op flag + ; TODO do something if the op flag is present + call .write_byte + pop rsi ; si = tte + + call .next_token + jge .break + + push rdi + push rsi + mov edi, .buffer_end - .buffer ; length of buffer + mov rsi, .buffer ; buffer location + mov dl, 0x48 + call elemb + pop rsi + pop rdi + cmp al, 1 + je .operator_2_register_const_64 + + push rdi + push rsi + mov edi, .buffer_end - .buffer ; length of buffer + mov rsi, .buffer ; buffer location + mov dl, 0x66 + call elemb + pop rsi + pop rdi + cmp al, 1 + je .operator_2_register_const_16 + + jmp .operator_2_register_const_32 + .operator_2_register_const_16: + mov ecx, [.tokens_processed] + mov ax, [TOKEN_TABLE_ADDR + 2 * rcx] ; get the next 2 bytes from the tt + mov ecx, [.buffer_pointer] + mov [rcx], ax ; and add them to the buffer + add ecx, 2 + mov [.buffer_pointer], ecx + jmp .operator_2_register_const_continue + .operator_2_register_const_32: + mov ecx, [.tokens_processed] + mov eax, [TOKEN_TABLE_ADDR + 2 * rcx] ; get the next 4 bytes from the tt + mov ecx, [.buffer_pointer] + mov [rcx], eax ; and add them to the buffer + add ecx, 4 + mov [.buffer_pointer], ecx + jmp .operator_2_register_const_continue + .operator_2_register_const_64: + mov ecx, [.tokens_processed] + mov rax, [TOKEN_TABLE_ADDR + 2 * rcx] ; get the next 8 bytes from the tt + mov ecx, [.buffer_pointer] + mov [rcx], rax ; and add them to the buffer + add ecx, 8 + mov [.buffer_pointer], ecx + jmp .operator_2_register_const_continue + .operator_2_register_const_continue: + ; skip the next 4 tokens (8 bytes) as prescribed by 0x2000 + call .next_token + jge .break + call .next_token + jge .break + call .next_token + jge .break + jmp .loop_next_token .loop_next_token: call .next_token @@ -558,21 +680,31 @@ assemble: .break: call .flush_write_buffer + push rsi + mov rsi, .msg_break + call print.debug + pop rsi ret .unexpected_token: + push rsi mov rsi, .msg_unexpected_token call print.error + pop rsi jmp halt .unsupported_memory_access: + push rsi mov rsi, .msg_unsupported_memory_access call print.error + pop rsi jmp halt .size_mismatch: + push rsi mov rsi, .msg_size_mismatch call print.error + pop rsi jmp halt ; procedures @@ -667,6 +799,8 @@ assemble: .msg_unexpected_token db "unexpected token, aborting", 0x0A, 0x00 .msg_unsupported_memory_access db "unsupported memory access, aborting", 0x0A, 0x00 .msg_size_mismatch db "size mismatch, aborting", 0x0A, 0x00 + .msg_break db "break", 0x0A, 0x00 + .msg_label db "label", 0x0A, 0x00 .msg_operator_0 db "operator_0", 0x0A, 0x00 .msg_operator_1 db "operator_1", 0x0A, 0x00 .msg_operator_1_memory db "operator_1_memory", 0x0A, 0x00 @@ -677,6 +811,7 @@ assemble: .msg_operator_2_register db "operator_2_register", 0x0A, 0x00 .msg_operator_2_register_memory db "operator_2_register_memory", 0x0A, 0x00 .msg_operator_2_register_register db "operator_2_register_register", 0x0A, 0x00 + .msg_operator_2_register_const db "operator_2_register_const", 0x0A, 0x00 .msg_potential_label db "potential_label", 0x0A, 0x00 ; ------------------------------------------------------------------------------ @@ -686,6 +821,17 @@ assemble: ; given a token table entry, returns the declared type in `tokens.by_id`. If ; there is no entry, returns UNRECOGNISED_ID_TYPE ; +; +-----+-----------------+ +; | hex | meaning | +; +-----+-----------------+ +; | 0x0 | ignored | +; | 0x1 | operator | +; | 0x2 | register | +; | 0x3 | pseudo-operator | +; | 0x4 | label | +; | 0xF | unknown | +; +-----+-----------------+ +; ; parameters: ; di = token table entry ; @@ -710,9 +856,17 @@ get_tte_type: inc eax jmp .loop .not_found: + shr edi, 12 + cmp edi, 0x3 + je .label + mov eax, UNRECOGNISED_ID_TYPE and eax, 0xF ret + + .label: + mov eax, 0x4 + ret .found: mov al, [2 + tokens.by_id + eax * 4] and eax, 0xF ; mask as expected @@ -1259,40 +1413,52 @@ tokenise: .expecting db E_COMMENT | E_NEWLINE | E_WHITESPACE | E_OPERATOR | E_LABEL .unexpected_whitespace: + push rsi mov rsi, .err_unexpected call print.error mov rsi, .msg_whitespace call print + pop rsi jmp halt .unexpected_comment: + push rsi mov rsi, .err_unexpected call print.error mov rsi, .msg_comment call print + pop rsi jmp halt .unexpected_newline: + push rsi mov rsi, .err_unexpected call print.error mov rsi, .msg_newline call print + pop rsi jmp halt .unexpected_comma: + push rsi mov rsi, .err_unexpected call print.error mov rsi, .msg_comma call print + pop rsi jmp halt .unexpected_operand: + push rsi mov rsi, .err_unexpected call print.error mov rsi, .msg_operand call print + pop rsi jmp halt .unexpected_operator: + push rsi mov rsi, .err_unexpected call print.error mov rsi, .msg_operator call print + pop rsi jmp halt .err_unexpected db "unexpected ", 0x00 .found db "found ", 0x00 @@ -1753,8 +1919,10 @@ print: ; ------------------------------------------------------------------------------ halt: + push rsi mov rsi, msg_halt call print + pop rsi hlt jmp halt @@ -1906,6 +2074,34 @@ add_label_hash: ; rax = index ret +; ------------------------------------------------------------------------------ +; add_label_address +; +; description: +; adds a label's address to the label table +; +; parameters +; rdi = lower 3 bytes: index of label table to add the address to +; rsi = 64-bit address to be added, relative to start of program +; +; returned +; rax = return value: 0 = success +; 1 = failure: label already in the table +; ------------------------------------------------------------------------------ + +add_label_address: + and edi, 0xFFF + shl rdi, 4 ; rdi * 16 + mov rax, [LABEL_TABLE_ADDR + rdi] + cmp rax, 0 + jne .ret_1 + mov [LABEL_TABLE_ADDR + 16 + rdi], rsi + xor eax, eax + ret + .ret_1: + mov eax, 1 + ret + ; ------------------------------------------------------------------------------ ; clear_token_table ;