|
|
|
|
@@ -85,13 +85,12 @@ start:
|
|
|
|
|
; ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
assemble:
|
|
|
|
|
xor eax, eax ; rax = number of tokens processed
|
|
|
|
|
; rdi = number of tokens in table
|
|
|
|
|
xor eax, eax ; rax = number of tokens processed
|
|
|
|
|
mov [.tokens_total], edi ; rdi = number of tokens in table
|
|
|
|
|
|
|
|
|
|
.loop:
|
|
|
|
|
push rdi
|
|
|
|
|
xor edi, edi
|
|
|
|
|
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; next tte
|
|
|
|
|
push rax
|
|
|
|
|
|
|
|
|
|
; di = tte of operator
|
|
|
|
|
.operator: ; if next tte's type is an operator:
|
|
|
|
|
@@ -134,12 +133,7 @@ assemble:
|
|
|
|
|
pop rsi
|
|
|
|
|
pop rdi
|
|
|
|
|
|
|
|
|
|
pop rax ; rax = number of tokens processed
|
|
|
|
|
pop rdi ; rdi = total number of tokens
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
jge .break
|
|
|
|
|
jmp .loop
|
|
|
|
|
jmp .loop_next_token
|
|
|
|
|
|
|
|
|
|
; di = tte of operator
|
|
|
|
|
.operator_1:
|
|
|
|
|
@@ -161,13 +155,8 @@ assemble:
|
|
|
|
|
pop rsi
|
|
|
|
|
pop rdi ; di = tte of operator
|
|
|
|
|
|
|
|
|
|
pop rax ; rax = number of tokens processed
|
|
|
|
|
pop rdi ; rdi = total number of tokens
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
call .next_token
|
|
|
|
|
jge .break
|
|
|
|
|
push rdi
|
|
|
|
|
push rax
|
|
|
|
|
xor edi, edi
|
|
|
|
|
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; di = next tte
|
|
|
|
|
|
|
|
|
|
@@ -175,7 +164,7 @@ assemble:
|
|
|
|
|
and di, 0xFF00
|
|
|
|
|
cmp di, 0x1000 ; check if token is a memory address
|
|
|
|
|
pop rdi ; di = next tte
|
|
|
|
|
je .operator_1_memory_access
|
|
|
|
|
je .operator_1_memory
|
|
|
|
|
|
|
|
|
|
push rdx
|
|
|
|
|
; di = next tte
|
|
|
|
|
@@ -186,17 +175,11 @@ assemble:
|
|
|
|
|
cmp al, 0x02 ; type: register
|
|
|
|
|
je .operator_1_register
|
|
|
|
|
|
|
|
|
|
pop rax ; rax = number of tokens processed
|
|
|
|
|
pop rdi ; rdi = total number of tokens
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
jge .break
|
|
|
|
|
jmp .loop
|
|
|
|
|
jmp .loop_next_token
|
|
|
|
|
|
|
|
|
|
; TODO figure out if this is relevant
|
|
|
|
|
.operator_1_memory_access:
|
|
|
|
|
.operator_1_memory:
|
|
|
|
|
push rsi
|
|
|
|
|
mov rsi, .msg_operator_1_memory_access
|
|
|
|
|
mov rsi, .msg_operator_1_memory
|
|
|
|
|
call print.debug
|
|
|
|
|
pop rsi
|
|
|
|
|
jmp .unsupported_memory_access
|
|
|
|
|
@@ -216,12 +199,7 @@ assemble:
|
|
|
|
|
; al = Mod R/M byte
|
|
|
|
|
call .output_byte
|
|
|
|
|
|
|
|
|
|
pop rax ; rax = number of tokens processed
|
|
|
|
|
pop rdi ; rdi = total number of tokens
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
jge .break
|
|
|
|
|
jmp .loop
|
|
|
|
|
jmp .loop_next_token
|
|
|
|
|
|
|
|
|
|
.operator_2:
|
|
|
|
|
push rsi
|
|
|
|
|
@@ -231,13 +209,8 @@ assemble:
|
|
|
|
|
|
|
|
|
|
mov cx, di ; cx = tte of operator
|
|
|
|
|
|
|
|
|
|
pop rax
|
|
|
|
|
pop rdi
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
call .next_token
|
|
|
|
|
jge .break
|
|
|
|
|
push rdi
|
|
|
|
|
push rax
|
|
|
|
|
xor edi, edi
|
|
|
|
|
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; di = next tte
|
|
|
|
|
|
|
|
|
|
@@ -245,7 +218,7 @@ assemble:
|
|
|
|
|
and di, 0xFF00
|
|
|
|
|
cmp di, 0x1000 ; check if token is a memory address
|
|
|
|
|
pop rdi ; di = next tte
|
|
|
|
|
je .operator_2_memory_access
|
|
|
|
|
je .operator_2_memory
|
|
|
|
|
|
|
|
|
|
push rcx
|
|
|
|
|
; di = next tte
|
|
|
|
|
@@ -256,16 +229,11 @@ assemble:
|
|
|
|
|
cmp al, 0x02 ; type: register
|
|
|
|
|
je .operator_2_register
|
|
|
|
|
|
|
|
|
|
pop rax ; rax = number of tokens processed
|
|
|
|
|
pop rdi ; rdi = total number of tokens
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
jge .break
|
|
|
|
|
jmp .loop
|
|
|
|
|
jmp .loop_next_token
|
|
|
|
|
|
|
|
|
|
.operator_2_memory_access:
|
|
|
|
|
.operator_2_memory:
|
|
|
|
|
push rsi
|
|
|
|
|
mov rsi, .msg_operator_2_memory_access
|
|
|
|
|
mov rsi, .msg_operator_2_memory
|
|
|
|
|
call print.debug
|
|
|
|
|
pop rsi
|
|
|
|
|
|
|
|
|
|
@@ -283,25 +251,15 @@ assemble:
|
|
|
|
|
call .output_byte
|
|
|
|
|
pop rdi
|
|
|
|
|
|
|
|
|
|
pop rax
|
|
|
|
|
pop rdi
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
call .next_token
|
|
|
|
|
jge .break
|
|
|
|
|
push rdi
|
|
|
|
|
push rax
|
|
|
|
|
xor edi, edi
|
|
|
|
|
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; di = next tte
|
|
|
|
|
|
|
|
|
|
mov si, di ; si = dst tte
|
|
|
|
|
|
|
|
|
|
pop rax
|
|
|
|
|
pop rdi
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
call .next_token
|
|
|
|
|
jge .break
|
|
|
|
|
push rdi
|
|
|
|
|
push rax
|
|
|
|
|
xor edi, edi
|
|
|
|
|
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; di = next tte
|
|
|
|
|
|
|
|
|
|
@@ -316,18 +274,13 @@ assemble:
|
|
|
|
|
; al = type of token
|
|
|
|
|
|
|
|
|
|
cmp al, 0x02
|
|
|
|
|
je .operator_2_memory_access_register
|
|
|
|
|
je .operator_2_memory_register
|
|
|
|
|
|
|
|
|
|
pop rax ; rax = number of tokens processed
|
|
|
|
|
pop rdi ; rdi = total number of tokens
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
jge .break
|
|
|
|
|
jmp .loop
|
|
|
|
|
jmp .loop_next_token
|
|
|
|
|
|
|
|
|
|
.operator_2_memory_access_register:
|
|
|
|
|
.operator_2_memory_register:
|
|
|
|
|
push rsi
|
|
|
|
|
mov rsi, .msg_operator_2_memory_access_register
|
|
|
|
|
mov rsi, .msg_operator_2_memory_register
|
|
|
|
|
call print.debug
|
|
|
|
|
pop rsi
|
|
|
|
|
|
|
|
|
|
@@ -338,12 +291,7 @@ assemble:
|
|
|
|
|
; al = Mod R/M byte
|
|
|
|
|
call .output_byte
|
|
|
|
|
|
|
|
|
|
pop rax ; rax = number of tokens processed
|
|
|
|
|
pop rdi ; rdi = total number of tokens
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
jge .break
|
|
|
|
|
jmp .loop
|
|
|
|
|
jmp .loop_next_token
|
|
|
|
|
|
|
|
|
|
.operator_2_register:
|
|
|
|
|
push rsi
|
|
|
|
|
@@ -363,13 +311,8 @@ assemble:
|
|
|
|
|
|
|
|
|
|
mov si, di ; si = dst tte
|
|
|
|
|
|
|
|
|
|
pop rax
|
|
|
|
|
pop rdi
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
call .next_token
|
|
|
|
|
jge .break
|
|
|
|
|
push rdi
|
|
|
|
|
push rax
|
|
|
|
|
xor edi, edi
|
|
|
|
|
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; di = next tte
|
|
|
|
|
|
|
|
|
|
@@ -377,7 +320,7 @@ assemble:
|
|
|
|
|
and di, 0xFF00
|
|
|
|
|
cmp di, 0x1000 ; check if token is a memory address
|
|
|
|
|
pop rdi ; di = next tte
|
|
|
|
|
je .operator_2_register_memory_access
|
|
|
|
|
je .operator_2_register_memory
|
|
|
|
|
|
|
|
|
|
; di = next tte
|
|
|
|
|
call get_tte_type
|
|
|
|
|
@@ -386,29 +329,19 @@ assemble:
|
|
|
|
|
cmp al, 0x02
|
|
|
|
|
je .operator_2_register_register
|
|
|
|
|
|
|
|
|
|
pop rax ; rax = number of tokens processed
|
|
|
|
|
pop rdi ; rdi = total number of tokens
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
jge .break
|
|
|
|
|
jmp .loop
|
|
|
|
|
jmp .loop_next_token
|
|
|
|
|
|
|
|
|
|
.operator_2_register_memory_access:
|
|
|
|
|
.operator_2_register_memory:
|
|
|
|
|
push rsi
|
|
|
|
|
mov rsi, .msg_operator_2_register_memory_access
|
|
|
|
|
mov rsi, .msg_operator_2_register_memory
|
|
|
|
|
call print.debug
|
|
|
|
|
pop rsi
|
|
|
|
|
|
|
|
|
|
cmp di, 0x1000 ; check if token is addressing to a register
|
|
|
|
|
jne .unsupported_memory_access ; if not, unsupported :/
|
|
|
|
|
|
|
|
|
|
pop rax
|
|
|
|
|
pop rdi
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
call .next_token
|
|
|
|
|
jge .break
|
|
|
|
|
push rdi
|
|
|
|
|
push rax
|
|
|
|
|
xor edi, edi
|
|
|
|
|
mov di, [rax * TOKEN_TABLE_ENTRY_SIZE + TOKEN_TABLE_ADDR] ; di = next tte
|
|
|
|
|
|
|
|
|
|
@@ -422,12 +355,7 @@ assemble:
|
|
|
|
|
; al = Mod R/M byte
|
|
|
|
|
call .output_byte
|
|
|
|
|
|
|
|
|
|
pop rax ; rax = number of tokens processed
|
|
|
|
|
pop rdi ; rdi = total number of tokens
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
jge .break
|
|
|
|
|
jmp .loop
|
|
|
|
|
jmp .loop_next_token
|
|
|
|
|
|
|
|
|
|
.operator_2_register_register:
|
|
|
|
|
push rsi
|
|
|
|
|
@@ -443,10 +371,10 @@ assemble:
|
|
|
|
|
; al = Mod R/M byte
|
|
|
|
|
call .output_byte
|
|
|
|
|
|
|
|
|
|
pop rax ; rax = number of tokens processed
|
|
|
|
|
pop rdi ; rdi = total number of tokens
|
|
|
|
|
inc rax
|
|
|
|
|
cmp rax, rdi
|
|
|
|
|
jmp .loop_next_token
|
|
|
|
|
|
|
|
|
|
.loop_next_token:
|
|
|
|
|
call .next_token
|
|
|
|
|
jge .break
|
|
|
|
|
jmp .loop
|
|
|
|
|
|
|
|
|
|
@@ -465,6 +393,18 @@ assemble:
|
|
|
|
|
|
|
|
|
|
; procedures
|
|
|
|
|
|
|
|
|
|
; add the line `jge .break` after call site
|
|
|
|
|
.next_token:
|
|
|
|
|
mov eax, [.tokens_processed]
|
|
|
|
|
mov edi, [.tokens_total]
|
|
|
|
|
inc eax
|
|
|
|
|
mov [.tokens_processed], eax
|
|
|
|
|
cmp eax, edi
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
.tokens_processed dd 0
|
|
|
|
|
.tokens_total dd 0
|
|
|
|
|
|
|
|
|
|
; al = byte to write
|
|
|
|
|
.output_byte:
|
|
|
|
|
mov edx, [.next_output_byte] ; get output byte's address
|
|
|
|
|
@@ -479,13 +419,13 @@ assemble:
|
|
|
|
|
.msg_unsupported_memory_access db "unsupported memory access, aborting", 0x0A, 0x00
|
|
|
|
|
.msg_operator_0 db "operator_0", 0x0A, 0x00
|
|
|
|
|
.msg_operator_1 db "operator_1", 0x0A, 0x00
|
|
|
|
|
.msg_operator_1_memory_access db "operator_1_memory_access", 0x0A, 0x00
|
|
|
|
|
.msg_operator_1_memory db "operator_1_memory", 0x0A, 0x00
|
|
|
|
|
.msg_operator_1_register db "operator_1_register", 0x0A, 0x00
|
|
|
|
|
.msg_operator_2 db "operator_2", 0x0A, 0x00
|
|
|
|
|
.msg_operator_2_memory_access db "operator_2_memory_access", 0x0A, 0x00
|
|
|
|
|
.msg_operator_2_memory_access_register db "operator_2_memory_access_register", 0x0A, 0x00
|
|
|
|
|
.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_memory_access db "operator_2_register_memory_access", 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
|
|
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------------------
|
|
|
|
|
@@ -597,20 +537,10 @@ get_ModRM:
|
|
|
|
|
call get_reg_bits
|
|
|
|
|
; al = reg bits
|
|
|
|
|
|
|
|
|
|
push rsi
|
|
|
|
|
mov rsi, .msg_normal_ModRM
|
|
|
|
|
call print.debug
|
|
|
|
|
pop rsi
|
|
|
|
|
|
|
|
|
|
mov bl, al ; bl = reg bits
|
|
|
|
|
jmp .continue
|
|
|
|
|
|
|
|
|
|
.pass_di_as_op_flag:
|
|
|
|
|
push rsi
|
|
|
|
|
mov rsi, .msg_op_flag
|
|
|
|
|
call print.debug
|
|
|
|
|
pop rsi
|
|
|
|
|
|
|
|
|
|
mov bl, dil ; bl = op flag
|
|
|
|
|
and bl, 111b ; mask
|
|
|
|
|
|
|
|
|
|
@@ -633,9 +563,6 @@ get_ModRM:
|
|
|
|
|
pop rbx
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
.msg_op_flag db "get_ModRM op_flag", 0x0A, 0x00
|
|
|
|
|
.msg_normal_ModRM db "get_ModRM normal_ModRM", 0x0A, 0x00
|
|
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------------------
|
|
|
|
|
; get_opcode
|
|
|
|
|
;
|
|
|
|
|
@@ -693,8 +620,7 @@ get_opcode:
|
|
|
|
|
jne .found_continue
|
|
|
|
|
|
|
|
|
|
shr dl, 4 ; if so, actually 1 further on dl byte
|
|
|
|
|
|
|
|
|
|
.found_continue
|
|
|
|
|
.found_continue:
|
|
|
|
|
mov al, [rsi + 2 + opcodes.by_id + rax]
|
|
|
|
|
and rax, 0xFF ; mask
|
|
|
|
|
and rdx, 0x0F ; mask
|
|
|
|
|
@@ -1441,10 +1367,10 @@ print:
|
|
|
|
|
call print
|
|
|
|
|
pop rsi
|
|
|
|
|
jmp print ; tail call
|
|
|
|
|
.debug_msg db "[DEBUG]: ", 0x00
|
|
|
|
|
.error_msg db "[ERROR]: ", 0x00
|
|
|
|
|
.test_msg db "[TEST]: ", 0x00
|
|
|
|
|
.warn_msg db "[WARN]: ", 0x00
|
|
|
|
|
.debug_msg db 0x1B, "[36m", "[DEBUG]: ", 0x1B, "[0m", 0x00
|
|
|
|
|
.error_msg db 0x1B, "[1;31m", "[ERROR]: ", 0x1B, "[0m", 0x00
|
|
|
|
|
.test_msg db 0x1B, "[1;33m", "[TEST]: ", 0x1B, "[0m", 0x00
|
|
|
|
|
.warn_msg db 0x1B, "[1;35m", "[WARN]: ", 0x1B, "[0m", 0x00
|
|
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------------------
|
|
|
|
|
; halt
|
|
|
|
|
@@ -1623,7 +1549,7 @@ clear_output_arena:
|
|
|
|
|
; data
|
|
|
|
|
; ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
align 4
|
|
|
|
|
align 16 ; for readability in hexdump
|
|
|
|
|
tokens:
|
|
|
|
|
.by_id:
|
|
|
|
|
dw 0x0000 ; rax
|
|
|
|
|
@@ -1935,7 +1861,7 @@ tokens:
|
|
|
|
|
dw 0x003F
|
|
|
|
|
.registers_end:
|
|
|
|
|
|
|
|
|
|
align 16
|
|
|
|
|
align 16 ; for readability in hexdump
|
|
|
|
|
opcodes:
|
|
|
|
|
.by_id:
|
|
|
|
|
; hlt
|
|
|
|
|
@@ -2079,7 +2005,7 @@ opcodes:
|
|
|
|
|
dd 0x00000000
|
|
|
|
|
.by_id_end:
|
|
|
|
|
|
|
|
|
|
msg_welcome db "Welcome to Twasm", 0x0A, 0x00
|
|
|
|
|
msg_welcome db 0x1B, "[35m", "Welcome to Twasm", 0x1B, "[0m", 0x0A, 0x00
|
|
|
|
|
msg_halt db "halted.", 0x0A, 0x00
|
|
|
|
|
|
|
|
|
|
whitespace_2 db " ", 0x0D
|
|
|
|
|
|