diff --git a/twasm/asm/main.asm b/twasm/asm/main.asm index 0784bdb..d607021 100644 --- a/twasm/asm/main.asm +++ b/twasm/asm/main.asm @@ -117,9 +117,10 @@ assemble: mov rsi, .msg_label call print.debug pop rsi + mov esi, [.next_output_byte] sub esi, OUTPUT_ADDR ; esi = relative address of label to start of program - and edi, 0xFFF ; edi = index to add address hash to + and edi, 0x0FFF ; edi = index to add address hash to call add_label_address jmp .loop_next_token .operator: @@ -171,8 +172,7 @@ assemble: call .get_next_tte mov rcx, rdi ; cx = operand tte pop rdi - push rcx - + push rcx ; pushes until after write_prefix_continue ; di = tte of operator mov sil, 0 ; dst=r/m @@ -285,7 +285,7 @@ assemble: ; of program mov eax, 0x04 ; al = first 4 bits: # bytes reserved ; 5th bit: abs flag - and edi, 0xFFF ; edi = index of hash + and edi, 0x0FFF ; edi = index of hash call add_awaiting_label mov al, 0xFF ; reserve space @@ -306,6 +306,7 @@ assemble: call .next_token jge .break call .get_next_tte + ; di = next tte push rdi and di, 0xFF00 @@ -491,6 +492,109 @@ assemble: cmp al, 0x02 ; check if token is a register je .operator_2_register_register ; if so, handle + cmp al, 0x04 ; check if token is a label + je .operator_2_register_label ; if so, handle + + jmp .unexpected_token ; otherwise, fail + .operator_2_register_label: + push rsi + mov rsi, .msg_operator_2_register_label + call print.debug + pop rsi ; si = dst tte + + push rsi + mov di, cx ; di = tte of operator + mov sil, 2 ; dst=r/m,src=imm + ; bl = operator flag byte + push rbx + and ebx, 1 + cmp bl, 1 ; bit8 flag + pop rbx + je .operator_2_register_label_get_opcode_8 + jmp .operator_2_register_label_get_opcode_continue + .operator_2_register_label_get_opcode_8: + mov sil, 3 ; dst=r/m,src=imm8 + .operator_2_register_label_get_opcode_continue: + call get_opcode + ; al = opcode + ; dl = flags + call .write_byte + mov edi, edx ; di = op flag + and edi, 0xFF + or edi, 0xFE00 + pop rsi ; si = r/m; dst tte + mov edx, 11b ; dl = mod bits + call get_ModRM + ; al = Mod R/M byte + call .write_byte + + push rbx + and ebx, 1 + cmp ebx, 1 ; bit8 flag + pop rbx + je .operator_2_register_label_8 + + 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_label_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_label_16 + + jmp .operator_2_register_label_32 + .operator_2_register_label_8: + mov esi, [.next_output_byte] + sub esi, OUTPUT_ADDR ; esi = relative address of label reference to start + mov eax, 0x11 ; al = first 4 bits: # bits reserved + ; 5th bit: abs flag + and edi, 0x0FFF ; edi = index of hash + call add_awaiting_label + mov al, 0xFF ; reserve space + call .write_byte + jmp .loop_next_token + .operator_2_register_label_16: + mov esi, [.next_output_byte] + sub esi, OUTPUT_ADDR ; esi = relative address of label reference to start + mov eax, 0x12 ; al = first 4 bits: # bits reserved + ; 5th bit: abs flag + and edi, 0x0FFF ; edi = index of hash + call add_awaiting_label + mov al, 0xFF ; reserve space + call .write_byte + call .write_byte + jmp .loop_next_token + .operator_2_register_label_32: + mov esi, [.next_output_byte] + sub esi, OUTPUT_ADDR ; esi = relative address of label reference to start + mov eax, 0x14 ; al = first 4 bits: # bits reserved + ; 5th bit: abs flag + and edi, 0x0FFF ; edi = index of hash + call add_awaiting_label + mov al, 0xFF ; reserve space + call .write_byte + call .write_byte + call .write_byte + call .write_byte + jmp .loop_next_token + .operator_2_register_label_64: + ; TODO do the B8+r variant :/ + jmp .size_mismatch + .operator_2_register_label_continue: jmp .unexpected_token .operator_2_register_memory: push rsi @@ -710,7 +814,7 @@ assemble: ; dl = op flag ; TODO do something if the op flag is present call .write_byte - mov edi, edx ; si = op flag + mov edi, edx ; di = op flag and edi, 0xFF or edi, 0xFE00 pop rsi ; si = r/m; dst tte @@ -804,6 +908,7 @@ assemble: ret .unexpected_token: + call .flush_write_buffer push rsi mov rsi, .msg_unexpected_token call print.error @@ -811,6 +916,7 @@ assemble: jmp halt .unsupported_memory_access: + call .flush_write_buffer push rsi mov rsi, .msg_unsupported_memory_access call print.error @@ -927,6 +1033,7 @@ assemble: .msg_operator_2_memory db "operator_2_memory", 0x0A, 0x00 .msg_operator_2_memory_register db "operator_2_memory_register", 0x0A, 0x00 .msg_operator_2_register db "operator_2_register", 0x0A, 0x00 + .msg_operator_2_register_label db "operator_2_register_label", 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 @@ -2272,7 +2379,7 @@ add_awaiting_label: .loop: cmp rax, AWAITING_LABEL_TABLE_SIZE jge .break - mov rcx, [AWAITING_LABEL_TABLE_SIZE + rax] + mov rcx, [AWAITING_LABEL_TABLE_ADDR + rax] cmp rcx, 0 ; empty slot je .break add rax, 16 @@ -3079,25 +3186,25 @@ program: db " ret", 0x0A db " .debug:", 0x0A db " push rsi", 0x0A - db " mov rsi, .debug_msg", 0x0A + db " mov esi, .debug_msg", 0x0A db " call print", 0x0A db " pop rsi", 0x0A db " jmp print ; tail call", 0x0A db " .error:", 0x0A db " push rsi", 0x0A - db " mov rsi, .error_msg", 0x0A + db " mov esi, .error_msg", 0x0A db " call print", 0x0A db " pop rsi", 0x0A db " jmp print ; tail call", 0x0A db " .test:", 0x0A db " push rsi", 0x0A - db " mov rsi, .test_msg", 0x0A + db " mov esi, .test_msg", 0x0A db " call print", 0x0A db " pop rsi", 0x0A db " jmp print ; tail call", 0x0A db " .warn:", 0x0A db " push rsi", 0x0A - db " mov rsi, .warn_msg", 0x0A + db " mov esi, .warn_msg", 0x0A db " call print", 0x0A db " pop rsi", 0x0A db " jmp print ; tail call", 0x0A