762 lines
24 KiB
NASM
762 lines
24 KiB
NASM
;; This assembler is a 2-pass compiler, permitting forward and backward label references.
|
|
;; It's also the first stage in this bootstrapping experiment that will
|
|
;; consume proper mnemonic assembly, rather than hex input.
|
|
|
|
section .bss
|
|
global buf
|
|
buf resb 0x100
|
|
labels resb 0x1000
|
|
section .data
|
|
_start_lbl db "_start", 0
|
|
|
|
ENC_RM equ 1
|
|
ENC_MR equ 2
|
|
ENC_MI equ 3
|
|
ENC_OI equ 4
|
|
ENC_M equ 5
|
|
ENC_O equ 6
|
|
ENC_I equ 7
|
|
ENC_MC equ 8 ; memory with cl
|
|
ENC_M1 equ 9 ; memory with 1
|
|
|
|
OPSIZE_8 equ 1
|
|
OPSIZE_16 equ 2
|
|
OPSIZE_32 equ 4
|
|
OPSIZE_64 equ 8
|
|
|
|
mnt:
|
|
mnemonics:
|
|
mnemonics_table:
|
|
MN_MOV db "mov", 0
|
|
MN_TEST db "test", 0
|
|
MN_XOR db "xor", 0
|
|
MN_OR db "or", 0
|
|
MN_AND db "and", 0
|
|
MN_SHL db "shl", 0
|
|
MN_SHR db "shr", 0
|
|
MN_INC db "inc", 0
|
|
MN_DEC db "dec", 0
|
|
MN_NEG db "neg", 0
|
|
MN_RET db "ret", 0
|
|
MN_NOT db "not", 0
|
|
MN_ADD db "add", 0
|
|
MN_SUB db "sub", 0
|
|
MN_IMUL db "imul", 0
|
|
MN_IDIV db "idiv", 0
|
|
MN_CMP db "cmp", 0
|
|
MN_LEA db "lea", 0
|
|
MN_PUSH db "push", 0
|
|
MN_POP db "pop", 0
|
|
MN_CMOVE db "cmovz", 0
|
|
MN_CMOVNE db "cmovnz", 0
|
|
MN_CMOVL db "cmovl", 0
|
|
MN_CMOVLE db "cmovle", 0
|
|
MN_CMOVG db "cmovg", 0
|
|
MN_CMOVGE db "cmovge", 0
|
|
MN_CMOVA db "cmova", 0
|
|
MN_CMOVAE db "cmovae", 0
|
|
MN_CMOVB db "cmovb", 0
|
|
MN_CMOVBE db "cmovbe", 0
|
|
MN_SETE db "sete", 0
|
|
MN_SETNE db "setne", 0
|
|
MN_SETL db "setl", 0
|
|
MN_SETLE db "setle", 0
|
|
MN_SETG db "setg", 0
|
|
MN_SETGE db "setge", 0
|
|
MN_SETA db "seta", 0
|
|
MN_SETAE db "setae", 0
|
|
MN_SETB db "setb", 0
|
|
MN_SETBE db "setbe", 0
|
|
MN_JE db "je", 0
|
|
MN_JNE db "jne", 0
|
|
MN_JL db "jl", 0
|
|
MN_JLE db "jle", 0
|
|
MN_JG db "jg", 0
|
|
MN_JGE db "jge", 0
|
|
MN_JA db "ja", 0
|
|
MN_JAE db "jae", 0
|
|
MN_JB db "jb", 0
|
|
MN_JBE db "jbe", 0
|
|
MN_JMP db "jmp", 0
|
|
MN_CALL db "call", 0
|
|
MN_XCHG db "xchg", 0
|
|
MN_SYSCALL db "syscall", 0
|
|
|
|
;; Opcodes support up to 2 operands
|
|
|
|
op_table:
|
|
;; MN_OFFS | NUM | SIZES | ENCOD | OPCODE | RM | PRE
|
|
dd mnt - MN_MOV, 2, 1, 1, ENC_MR, 88h, 00, 00h
|
|
dd mnt - MN_MOV, 2, 2, 2, ENC_MR, 89h, 00, 66h
|
|
dd mnt - MN_MOV, 2, 4, 4, ENC_MR, 89h, 00, 00h
|
|
dd mnt - MN_MOV, 2, 8, 8, ENC_MR, 89h, 00, 00h
|
|
dd mnt - MN_MOV, 2, 1, 1, ENC_RM, 8Ah, 00, 00h
|
|
dd mnt - MN_MOV, 2, 2, 2, ENC_RM, 8Bh, 00, 66h
|
|
dd mnt - MN_MOV, 2, 4, 4, ENC_RM, 8Bh, 00, 00h
|
|
dd mnt - MN_MOV, 2, 8, 8, ENC_RM, 8Bh, 00, 00h
|
|
dd mnt - MN_MOV, 2, 1, 1, ENC_OI, 0B0h, 00, 00h
|
|
dd mnt - MN_MOV, 2, 2, 2, ENC_OI, 0B8h, 00, 66h
|
|
dd mnt - MN_MOV, 2, 4, 4, ENC_OI, 0B8h, 00, 00h
|
|
dd mnt - MN_MOV, 2, 8, 8, ENC_OI, 0B8h, 00, 00h
|
|
dd mnt - MN_MOV, 2, 1, 1, ENC_MI, 0C6h, 00, 00h
|
|
dd mnt - MN_MOV, 2, 2, 2, ENC_MI, 0C7h, 00, 66h
|
|
dd mnt - MN_MOV, 2, 4, 4, ENC_MI, 0C7h, 00, 00h
|
|
dd mnt - MN_MOV, 2, 8, 4, ENC_MI, 0C7h, 00, 00h
|
|
|
|
dd mnt - MN_TEST, 2, 1, 1, ENC_MR, 84h, 00, 00h
|
|
dd mnt - MN_TEST, 2, 2, 2, ENC_MR, 85h, 00, 66h
|
|
dd mnt - MN_TEST, 2, 4, 4, ENC_MR, 85h, 00, 00h
|
|
dd mnt - MN_TEST, 2, 8, 8, ENC_MR, 85h, 00, 00h
|
|
dd mnt - MN_TEST, 2, 1, 1, ENC_MI, 0F6h, 00, 00h
|
|
dd mnt - MN_TEST, 2, 2, 2, ENC_MI, 0F7h, 00, 66h
|
|
dd mnt - MN_TEST, 2, 4, 4, ENC_MI, 0F7h, 00, 00h
|
|
dd mnt - MN_TEST, 2, 8, 4, ENC_MI, 0F7h, 00, 00h
|
|
|
|
dd mnt - MN_XOR, 2, 1, 1, ENC_MR, 30h, 00, 00h
|
|
dd mnt - MN_XOR, 2, 2, 2, ENC_MR, 31h, 00, 66h
|
|
dd mnt - MN_XOR, 2, 4, 4, ENC_MR, 31h, 00, 00h
|
|
dd mnt - MN_XOR, 2, 8, 8, ENC_MR, 31h, 00, 00h
|
|
dd mnt - MN_XOR, 2, 1, 1, ENC_RM, 32h, 00, 00h
|
|
dd mnt - MN_XOR, 2, 2, 2, ENC_RM, 33h, 00, 66h
|
|
dd mnt - MN_XOR, 2, 4, 4, ENC_RM, 33h, 00, 00h
|
|
dd mnt - MN_XOR, 2, 8, 8, ENC_RM, 33h, 00, 00h
|
|
dd mnt - MN_XOR, 2, 1, 1, ENC_MI, 80h, 06, 00h
|
|
dd mnt - MN_XOR, 2, 2, 2, ENC_MI, 81h, 06, 66h
|
|
dd mnt - MN_XOR, 2, 4, 4, ENC_MI, 81h, 06, 00h
|
|
dd mnt - MN_XOR, 2, 8, 4, ENC_MI, 81h, 06, 00h
|
|
|
|
dd mnt - MN_AND, 2, 1, 1, ENC_MR, 20h, 00, 00h
|
|
dd mnt - MN_AND, 2, 2, 2, ENC_MR, 21h, 00, 66h
|
|
dd mnt - MN_AND, 2, 4, 4, ENC_MR, 21h, 00, 00h
|
|
dd mnt - MN_AND, 2, 8, 8, ENC_MR, 21h, 00, 00h
|
|
dd mnt - MN_AND, 2, 1, 1, ENC_RM, 22h, 00, 00h
|
|
dd mnt - MN_AND, 2, 2, 2, ENC_RM, 23h, 00, 66h
|
|
dd mnt - MN_AND, 2, 4, 4, ENC_RM, 23h, 00, 00h
|
|
dd mnt - MN_AND, 2, 8, 8, ENC_RM, 23h, 00, 00h
|
|
dd mnt - MN_AND, 2, 1, 1, ENC_MI, 80h, 04, 00h
|
|
dd mnt - MN_AND, 2, 2, 2, ENC_MI, 81h, 04, 66h
|
|
dd mnt - MN_AND, 2, 4, 4, ENC_MI, 81h, 04, 00h
|
|
dd mnt - MN_AND, 2, 8, 4, ENC_MI, 81h, 04, 00h
|
|
dd mnt - MN_AND, 2, 1, 1, ENC_MI, 83h, 04, 00h
|
|
dd mnt - MN_AND, 2, 2, 1, ENC_MI, 83h, 04, 66h
|
|
dd mnt - MN_AND, 2, 4, 1, ENC_MI, 83h, 04, 00h
|
|
dd mnt - MN_AND, 2, 8, 1, ENC_MI, 83h, 04, 00h
|
|
|
|
dd mnt - MN_OR, 2, 1, 1, ENC_MR, 08h, 00, 00h
|
|
dd mnt - MN_OR, 2, 2, 2, ENC_MR, 09h, 00, 66h
|
|
dd mnt - MN_OR, 2, 4, 4, ENC_MR, 09h, 00, 00h
|
|
dd mnt - MN_OR, 2, 8, 8, ENC_MR, 09h, 00, 00h
|
|
dd mnt - MN_OR, 2, 1, 1, ENC_RM, 0Ah, 00, 00h
|
|
dd mnt - MN_OR, 2, 2, 2, ENC_RM, 0Bh, 00, 66h
|
|
dd mnt - MN_OR, 2, 4, 4, ENC_RM, 0Bh, 00, 00h
|
|
dd mnt - MN_OR, 2, 8, 8, ENC_RM, 0Bh, 00, 00h
|
|
dd mnt - MN_OR, 2, 1, 1, ENC_MI, 80h, 01, 00h
|
|
dd mnt - MN_OR, 2, 2, 2, ENC_MI, 81h, 01, 66h
|
|
dd mnt - MN_OR, 2, 4, 4, ENC_MI, 81h, 01, 00h
|
|
dd mnt - MN_OR, 2, 8, 4, ENC_MI, 81h, 01, 00h
|
|
dd mnt - MN_OR, 2, 1, 1, ENC_MI, 83h, 01, 00h
|
|
dd mnt - MN_OR, 2, 2, 1, ENC_MI, 83h, 01, 66h
|
|
dd mnt - MN_OR, 2, 4, 1, ENC_MI, 83h, 01, 00h
|
|
dd mnt - MN_OR, 2, 8, 1, ENC_MI, 83h, 01, 00h
|
|
|
|
; dd mnt - MN_SHL, 2, 1, 1, ENC_M1, 0D0h, 04, 00h
|
|
; dd mnt - MN_SHL, 2, 2, 1, ENC_M1, 0D1h, 04, 66h
|
|
; dd mnt - MN_SHL, 2, 4, 1, ENC_M1, 0D1h, 04, 00h
|
|
; dd mnt - MN_SHL, 2, 8, 1, ENC_M1, 0D1h, 04, 00h
|
|
dd mnt - MN_SHL, 2, 1, 1, ENC_MC, 0D2h, 04, 00h
|
|
dd mnt - MN_SHL, 2, 2, 1, ENC_MC, 0D3h, 04, 66h
|
|
dd mnt - MN_SHL, 2, 4, 1, ENC_MC, 0D3h, 04, 00h
|
|
dd mnt - MN_SHL, 2, 8, 1, ENC_MC, 0D3h, 04, 00h
|
|
dd mnt - MN_SHL, 2, 1, 1, ENC_MI, 0C0h, 04, 00h
|
|
dd mnt - MN_SHL, 2, 2, 1, ENC_MI, 0C1h, 04, 66h
|
|
dd mnt - MN_SHL, 2, 4, 1, ENC_MI, 0C1h, 04, 00h
|
|
dd mnt - MN_SHL, 2, 8, 1, ENC_MI, 0C1h, 04, 00h
|
|
|
|
dd mnt - MN_SHR, 2, 1, 1, ENC_MC, 0D2h, 05, 00h
|
|
dd mnt - MN_SHR, 2, 2, 1, ENC_MC, 0D3h, 05, 66h
|
|
dd mnt - MN_SHR, 2, 4, 1, ENC_MC, 0D3h, 05, 00h
|
|
dd mnt - MN_SHR, 2, 8, 1, ENC_MC, 0D3h, 05, 00h
|
|
dd mnt - MN_SHR, 2, 1, 1, ENC_MI, 0C0h, 05, 00h
|
|
dd mnt - MN_SHR, 2, 2, 1, ENC_MI, 0C1h, 05, 66h
|
|
dd mnt - MN_SHR, 2, 4, 1, ENC_MI, 0C1h, 05, 00h
|
|
dd mnt - MN_SHR, 2, 8, 1, ENC_MI, 0C1h, 05, 00h
|
|
|
|
dd mnt - MN_INC, 1, 1, 0, ENC_M, 0FEh, 00, 00h
|
|
dd mnt - MN_INC, 1, 2, 0, ENC_M, 0FFh, 00, 66h
|
|
dd mnt - MN_INC, 1, 4, 0, ENC_M, 0FFh, 00, 00h
|
|
dd mnt - MN_INC, 1, 8, 0, ENC_M, 0FFh, 00, 00h
|
|
|
|
dd mnt - MN_DEC, 1, 1, 0, ENC_M, 0FEh, 01, 00h
|
|
dd mnt - MN_DEC, 1, 2, 0, ENC_M, 0FFh, 01, 66h
|
|
dd mnt - MN_DEC, 1, 4, 0, ENC_M, 0FFh, 01, 00h
|
|
dd mnt - MN_DEC, 1, 8, 0, ENC_M, 0FFh, 01, 00h
|
|
|
|
dd mnt - MN_NEG, 1, 1, 0, ENC_M, 0F6h, 03, 00h
|
|
dd mnt - MN_NEG, 1, 2, 0, ENC_M, 0F7h, 03, 66h
|
|
dd mnt - MN_NEG, 1, 4, 0, ENC_M, 0F7h, 03, 00h
|
|
dd mnt - MN_NEG, 1, 8, 0, ENC_M, 0F7h, 03, 00h
|
|
|
|
dd mnt - MN_RET, 0, 0, 0, 0, 0C3h, 00, 00h
|
|
|
|
dd mnt - MN_NOT, 1, 1, 0, ENC_M, 0F6h, 02, 00h
|
|
dd mnt - MN_NOT, 1, 2, 0, ENC_M, 0F7h, 02, 66h
|
|
dd mnt - MN_NOT, 1, 4, 0, ENC_M, 0F7h, 02, 00h
|
|
dd mnt - MN_NOT, 1, 8, 0, ENC_M, 0F7h, 02, 00h
|
|
|
|
dd mnt - MN_ADD, 2, 1, 1, ENC_MR, 00h, 00, 00h
|
|
dd mnt - MN_ADD, 2, 2, 2, ENC_MR, 01h, 00, 66h
|
|
dd mnt - MN_ADD, 2, 4, 4, ENC_MR, 01h, 00, 00h
|
|
dd mnt - MN_ADD, 2, 8, 8, ENC_MR, 01h, 00, 00h
|
|
dd mnt - MN_ADD, 2, 1, 1, ENC_RM, 02h, 00, 00h
|
|
dd mnt - MN_ADD, 2, 2, 2, ENC_RM, 03h, 00, 66h
|
|
dd mnt - MN_ADD, 2, 4, 4, ENC_RM, 03h, 00, 00h
|
|
dd mnt - MN_ADD, 2, 8, 8, ENC_RM, 03h, 00, 00h
|
|
dd mnt - MN_ADD, 2, 1, 1, ENC_MI, 80h, 00, 00h
|
|
dd mnt - MN_ADD, 2, 2, 2, ENC_MI, 81h, 00, 66h
|
|
dd mnt - MN_ADD, 2, 4, 4, ENC_MI, 81h, 00, 00h
|
|
dd mnt - MN_ADD, 2, 8, 4, ENC_MI, 81h, 00, 00h
|
|
|
|
dd mnt - MN_SUB, 2, 1, 1, ENC_MR, 28h, 00, 00h
|
|
dd mnt - MN_SUB, 2, 2, 2, ENC_MR, 29h, 00, 66h
|
|
dd mnt - MN_SUB, 2, 4, 4, ENC_MR, 29h, 00, 00h
|
|
dd mnt - MN_SUB, 2, 8, 8, ENC_MR, 29h, 00, 00h
|
|
dd mnt - MN_SUB, 2, 1, 1, ENC_RM, 2Ah, 00, 00h
|
|
dd mnt - MN_SUB, 2, 2, 2, ENC_RM, 2Bh, 00, 66h
|
|
dd mnt - MN_SUB, 2, 4, 4, ENC_RM, 2Bh, 00, 00h
|
|
dd mnt - MN_SUB, 2, 8, 8, ENC_RM, 2Bh, 00, 00h
|
|
dd mnt - MN_SUB, 2, 1, 1, ENC_MI, 80h, 05, 00h
|
|
dd mnt - MN_SUB, 2, 2, 2, ENC_MI, 81h, 05, 66h
|
|
dd mnt - MN_SUB, 2, 4, 4, ENC_MI, 81h, 05, 00h
|
|
dd mnt - MN_SUB, 2, 8, 4, ENC_MI, 81h, 05, 00h
|
|
|
|
dd mnt - MN_IMUL, 1, 1, 0, ENC_M, 0F6h, 05, 00h
|
|
dd mnt - MN_IMUL, 1, 2, 0, ENC_M, 0F7h, 05, 66h
|
|
dd mnt - MN_IMUL, 1, 4, 0, ENC_M, 0F7h, 05, 00h
|
|
dd mnt - MN_IMUL, 1, 8, 0, ENC_M, 0F7h, 05, 00h
|
|
dd mnt - MN_IMUL, 2, 2, 1, ENC_RM, 0FAFh, 00, 66h
|
|
dd mnt - MN_IMUL, 2, 4, 1, ENC_RM, 0FAFh, 00, 00h
|
|
dd mnt - MN_IMUL, 2, 8, 1, ENC_RM, 0FAFh, 00, 00h
|
|
|
|
dd mnt - MN_IDIV, 1, 1, 0, ENC_M, 0F6h, 07, 00h
|
|
dd mnt - MN_IDIV, 1, 2, 0, ENC_M, 0F7h, 07, 66h
|
|
dd mnt - MN_IDIV, 1, 4, 0, ENC_M, 0F7h, 07, 00h
|
|
dd mnt - MN_IDIV, 1, 8, 0, ENC_M, 0F7h, 07, 00h
|
|
|
|
dd mnt - MN_CMP, 2, 1, 1, ENC_MR, 38h, 00, 00h
|
|
dd mnt - MN_CMP, 2, 2, 2, ENC_MR, 39h, 00, 66h
|
|
dd mnt - MN_CMP, 2, 4, 4, ENC_MR, 39h, 00, 00h
|
|
dd mnt - MN_CMP, 2, 8, 8, ENC_MR, 39h, 00, 00h
|
|
dd mnt - MN_CMP, 2, 1, 1, ENC_RM, 3Ah, 00, 00h
|
|
dd mnt - MN_CMP, 2, 2, 2, ENC_RM, 3Bh, 00, 66h
|
|
dd mnt - MN_CMP, 2, 4, 4, ENC_RM, 3Bh, 00, 00h
|
|
dd mnt - MN_CMP, 2, 8, 8, ENC_RM, 3Bh, 00, 00h
|
|
dd mnt - MN_CMP, 2, 1, 1, ENC_MI, 80h, 07, 00h
|
|
dd mnt - MN_CMP, 2, 2, 2, ENC_MI, 81h, 07, 66h
|
|
dd mnt - MN_CMP, 2, 4, 4, ENC_MI, 81h, 07, 00h
|
|
dd mnt - MN_CMP, 2, 8, 4, ENC_MI, 81h, 07, 00h
|
|
|
|
dd mnt - MN_LEA, 2, 2, 4, ENC_RM, 8Dh, 00, 6667h
|
|
dd mnt - MN_LEA, 2, 2, 8, ENC_RM, 8Dh, 00, 66h
|
|
dd mnt - MN_LEA, 2, 4, 4, ENC_RM, 8Dh, 00, 67h
|
|
dd mnt - MN_LEA, 2, 4, 8, ENC_RM, 8Dh, 00, 00h
|
|
dd mnt - MN_LEA, 2, 8, 4, ENC_RM, 8Dh, 00, 67h
|
|
dd mnt - MN_LEA, 2, 8, 8, ENC_RM, 8Dh, 00, 00h
|
|
|
|
dd mnt - MN_PUSH, 1, 2, 0, ENC_O, 50h, 00, 66h
|
|
dd mnt - MN_PUSH, 1, 8, 0, ENC_O, 50h, 00, 00h
|
|
dd mnt - MN_PUSH, 1, 2, 0, ENC_M, 0FFh, 06, 66h
|
|
dd mnt - MN_PUSH, 1, 8, 0, ENC_M, 0FFh, 06, 00h
|
|
dd mnt - MN_PUSH, 1, 1, 0, ENC_I, 06Ah, 00, 00h
|
|
dd mnt - MN_PUSH, 1, 2, 0, ENC_I, 06Ah, 00, 66h
|
|
dd mnt - MN_PUSH, 1, 4, 0, ENC_I, 06Ah, 00, 00h
|
|
|
|
dd mnt - MN_POP, 1, 2, 0, ENC_O, 58h, 00, 66h
|
|
dd mnt - MN_POP, 1, 8, 0, ENC_O, 58h, 00, 00h
|
|
dd mnt - MN_POP, 1, 2, 0, ENC_M, 0FFh, 07, 66h
|
|
dd mnt - MN_POP, 1, 8, 0, ENC_M, 0FFh, 07, 00h
|
|
dd mnt - MN_POP, 1, 1, 0, ENC_I, 07Ah, 00, 00h
|
|
dd mnt - MN_POP, 1, 2, 0, ENC_I, 07Ah, 00, 66h
|
|
dd mnt - MN_POP, 1, 4, 0, ENC_I, 07Ah, 00, 00h
|
|
|
|
dd mnt - MN_SYSCALL, 0, 0, 0, 0, 0F05h, 00, 00h
|
|
|
|
dd mnt - MN_JMP, 1, 1, 0, ENC_I, 0EBh, 00, 00h
|
|
dd mnt - MN_JMP, 1, 4, 0, ENC_I, 0E9h, 00, 00h
|
|
dd mnt - MN_JMP, 1, 8, 0, ENC_M, 0FFh, 04, 00h
|
|
|
|
dd mnt - MN_CALL, 1, 4, 0, ENC_I, 0E8h, 00, 00h
|
|
dd mnt - MN_CALL, 1, 8, 0, ENC_M, 0FFh, 02, 00h
|
|
|
|
dd mnt - MN_XCHG, 2, 1, 1, ENC_MR, 86h, 00, 00h
|
|
dd mnt - MN_XCHG, 2, 2, 2, ENC_MR, 87h, 00, 66h
|
|
dd mnt - MN_XCHG, 2, 4, 4, ENC_MR, 87h, 00, 00h
|
|
dd mnt - MN_XCHG, 2, 8, 8, ENC_MR, 87h, 00, 00h
|
|
dd mnt - MN_XCHG, 2, 1, 1, ENC_RM, 86h, 00, 00h
|
|
dd mnt - MN_XCHG, 2, 2, 2, ENC_RM, 87h, 00, 66h
|
|
dd mnt - MN_XCHG, 2, 4, 4, ENC_RM, 87h, 00, 00h
|
|
dd mnt - MN_XCHG, 2, 8, 8, ENC_RM, 87h, 00, 00h
|
|
|
|
|
|
dd mnt - MN_CMOVE, 2, 2, 2, ENC_RM, 0F44h, 00, 66h
|
|
dd mnt - MN_CMOVE, 2, 4, 4, ENC_RM, 0F44h, 00, 00h
|
|
dd mnt - MN_CMOVE, 2, 8, 8, ENC_RM, 0F44h, 00, 00h
|
|
|
|
dd mnt - MN_CMOVNE, 2, 2, 2, ENC_RM, 0F45h, 00, 66h
|
|
dd mnt - MN_CMOVNE, 2, 4, 4, ENC_RM, 0F45h, 00, 00h
|
|
dd mnt - MN_CMOVNE, 2, 8, 8, ENC_RM, 0F45h, 00, 00h
|
|
|
|
dd mnt - MN_CMOVL, 2, 2, 2, ENC_RM, 0F4Ch, 00, 66h
|
|
dd mnt - MN_CMOVL, 2, 4, 4, ENC_RM, 0F4Ch, 00, 00h
|
|
dd mnt - MN_CMOVL, 2, 8, 8, ENC_RM, 0F4Ch, 00, 00h
|
|
|
|
dd mnt - MN_CMOVLE, 2, 2, 2, ENC_RM, 0F4Eh, 00, 66h
|
|
dd mnt - MN_CMOVLE, 2, 4, 4, ENC_RM, 0F4Eh, 00, 00h
|
|
dd mnt - MN_CMOVLE, 2, 8, 8, ENC_RM, 0F4Eh, 00, 00h
|
|
|
|
dd mnt - MN_CMOVG, 2, 2, 2, ENC_RM, 0F4Fh, 00, 66h
|
|
dd mnt - MN_CMOVG, 2, 4, 4, ENC_RM, 0F4Fh, 00, 00h
|
|
dd mnt - MN_CMOVG, 2, 8, 8, ENC_RM, 0F4Fh, 00, 00h
|
|
|
|
dd mnt - MN_CMOVGE, 2, 2, 2, ENC_RM, 0F4Dh, 00, 66h
|
|
dd mnt - MN_CMOVGE, 2, 4, 4, ENC_RM, 0F4Dh, 00, 00h
|
|
dd mnt - MN_CMOVGE, 2, 8, 8, ENC_RM, 0F4Dh, 00, 00h
|
|
|
|
dd mnt - MN_CMOVA, 2, 2, 2, ENC_RM, 0F47h, 00, 66h
|
|
dd mnt - MN_CMOVA, 2, 4, 4, ENC_RM, 0F47h, 00, 00h
|
|
dd mnt - MN_CMOVA, 2, 8, 8, ENC_RM, 0F47h, 00, 00h
|
|
|
|
dd mnt - MN_CMOVAE, 2, 2, 2, ENC_RM, 0F43h, 00, 66h
|
|
dd mnt - MN_CMOVAE, 2, 4, 4, ENC_RM, 0F43h, 00, 00h
|
|
dd mnt - MN_CMOVAE, 2, 8, 8, ENC_RM, 0F43h, 00, 00h
|
|
|
|
dd mnt - MN_CMOVB, 2, 2, 2, ENC_RM, 0F42h, 00, 66h
|
|
dd mnt - MN_CMOVB, 2, 4, 4, ENC_RM, 0F42h, 00, 00h
|
|
dd mnt - MN_CMOVB, 2, 8, 8, ENC_RM, 0F42h, 00, 00h
|
|
|
|
dd mnt - MN_CMOVBE, 2, 2, 2, ENC_RM, 0F46h, 00, 66h
|
|
dd mnt - MN_CMOVBE, 2, 4, 4, ENC_RM, 0F46h, 00, 00h
|
|
dd mnt - MN_CMOVBE, 2, 8, 8, ENC_RM, 0F46h, 00, 00h
|
|
|
|
dd mnt - MN_SETE, 1, 1, 0, ENC_M, 0F94h, 00, 00h
|
|
dd mnt - MN_SETNE, 1, 1, 0, ENC_M, 0F95h, 00, 00h
|
|
dd mnt - MN_SETL, 1, 1, 0, ENC_M, 0F9Ch, 00, 00h
|
|
dd mnt - MN_SETLE, 1, 1, 0, ENC_M, 0F9Eh, 00, 00h
|
|
dd mnt - MN_SETG, 1, 1, 0, ENC_M, 0F9Fh, 00, 00h
|
|
dd mnt - MN_SETGE, 1, 1, 0, ENC_M, 0F9Dh, 00, 00h
|
|
dd mnt - MN_SETA, 1, 1, 0, ENC_M, 0F97h, 00, 00h
|
|
dd mnt - MN_SETAE, 1, 1, 0, ENC_M, 0F93h, 00, 00h
|
|
dd mnt - MN_SETB, 1, 1, 0, ENC_M, 0F92h, 00, 00h
|
|
dd mnt - MN_SETBE, 1, 1, 0, ENC_M, 0F96h, 00, 00h
|
|
|
|
dd mnt - MN_JE, 1, 1, 0, ENC_I, 74h, 00, 00h
|
|
dd mnt - MN_JNE, 1, 1, 0, ENC_I, 75h, 00, 00h
|
|
dd mnt - MN_JL, 1, 1, 0, ENC_I, 7Ch, 00, 00h
|
|
dd mnt - MN_JLE, 1, 1, 0, ENC_I, 7Eh, 00, 00h
|
|
dd mnt - MN_JG, 1, 1, 0, ENC_I, 7Fh, 00, 00h
|
|
dd mnt - MN_JGE, 1, 1, 0, ENC_I, 7Dh, 00, 00h
|
|
dd mnt - MN_JA, 1, 1, 0, ENC_I, 77h, 00, 00h
|
|
dd mnt - MN_JAE, 1, 1, 0, ENC_I, 73h, 00, 00h
|
|
dd mnt - MN_JB, 1, 1, 0, ENC_I, 72h, 00, 00h
|
|
dd mnt - MN_JBE, 1, 1, 0, ENC_I, 76h, 00, 00h
|
|
|
|
dd mnt - MN_JE, 1, 4, 0, ENC_I, 0F84h, 00, 00h
|
|
dd mnt - MN_JNE, 1, 4, 0, ENC_I, 0F85h, 00, 00h
|
|
dd mnt - MN_JL, 1, 4, 0, ENC_I, 0F8Ch, 00, 00h
|
|
dd mnt - MN_JLE, 1, 4, 0, ENC_I, 0F8Eh, 00, 00h
|
|
dd mnt - MN_JG, 1, 4, 0, ENC_I, 0F8Fh, 00, 00h
|
|
dd mnt - MN_JGE, 1, 4, 0, ENC_I, 0F8Dh, 00, 00h
|
|
dd mnt - MN_JA, 1, 4, 0, ENC_I, 0F87h, 00, 00h
|
|
dd mnt - MN_JAE, 1, 4, 0, ENC_I, 0F83h, 00, 00h
|
|
dd mnt - MN_JB, 1, 4, 0, ENC_I, 0F82h, 00, 00h
|
|
dd mnt - MN_JBE, 1, 4, 0, ENC_I, 0F86h, 00, 00h
|
|
op_table_end:
|
|
dd 0 ; 231 entries
|
|
|
|
section .text
|
|
|
|
;; format dil as hex u8 into $ax
|
|
format_u8:
|
|
xor ecx, ecx
|
|
; take upper nibble >> 4
|
|
movzx eax, dil
|
|
shr eax, 4
|
|
; add 0x30
|
|
add eax, 0x30
|
|
; add (>= 0xA) * 0x7
|
|
cmp eax, 0x39
|
|
seta cl
|
|
lea eax, [eax + ecx * 8]
|
|
sub eax, ecx
|
|
and edi, 0x0F
|
|
add edi, 0x30
|
|
cmp edi, 0x39
|
|
seta cl
|
|
lea edi, [edi + ecx * 8]
|
|
sub edi, ecx
|
|
shl edi, 8
|
|
or ax, di
|
|
ret
|
|
|
|
;; format $edi as hex into $rax
|
|
format_u32:
|
|
sub rsp, 16
|
|
mov dword [rsp], edi
|
|
call format_u8
|
|
mov word [rsp + 14], ax
|
|
mov dil, byte [rsp + 1]
|
|
call format_u8
|
|
mov word [rsp + 12], ax
|
|
mov dil, byte [rsp + 2]
|
|
call format_u8
|
|
mov word [rsp + 10], ax
|
|
mov dil, byte [rsp + 3]
|
|
call format_u8
|
|
mov word [rsp + 8], ax
|
|
mov rax, qword [rsp + 8]
|
|
add rsp, 16
|
|
ret
|
|
|
|
print_u8:
|
|
call format_u8
|
|
sub rsp, 8
|
|
mov word [rsp], ax
|
|
lea rdi, [rsp]
|
|
mov rsi, 2
|
|
call print_str
|
|
add rsp, 8
|
|
ret
|
|
|
|
print_u32:
|
|
call format_u32
|
|
sub rsp, 8
|
|
mov qword [rsp], rax
|
|
lea rdi, [rsp]
|
|
mov rsi, 8
|
|
call print_str
|
|
add rsp, 8
|
|
ret
|
|
|
|
;; print $rsi bytes from $rdi to stdout
|
|
print_str:
|
|
mov rax, 1
|
|
mov rdx, rsi
|
|
mov rsi, rdi
|
|
mov rdi, 1
|
|
syscall
|
|
ret
|
|
|
|
tab: db 9
|
|
print_tab:
|
|
lea rsi, [rel tab]
|
|
mov rdx, 1
|
|
mov rax, 1
|
|
mov rdi, 1
|
|
syscall
|
|
ret
|
|
|
|
nl: db 10
|
|
print_nl:
|
|
lea rsi, [rel nl]
|
|
mov rdx, 1
|
|
mov rax, 1
|
|
mov rdi, 1
|
|
syscall
|
|
ret
|
|
|
|
;; print the $rdi-th entry in the op_table
|
|
op_table_entry_print:
|
|
sub rsp, 8
|
|
lea rax, [rel op_table]
|
|
lea rdi, [rdi * 4]
|
|
lea rax, [rax + rdi * 8]
|
|
mov qword [rsp], rax
|
|
|
|
lea rdi, [rel mnemonics]
|
|
movsx rax, dword [rax]
|
|
sub rdi, rax
|
|
call strlen
|
|
mov rsi, rax
|
|
call print_str ; mnemonic
|
|
call print_tab
|
|
|
|
mov rax, qword [rsp]
|
|
mov edi, dword [rax + 4]
|
|
call print_u8 ; num operands
|
|
call print_tab
|
|
|
|
mov rax, qword [rsp]
|
|
mov edi, dword [rax + 8]
|
|
call print_u8 ; operand 0 size
|
|
call print_tab
|
|
|
|
mov rax, qword [rsp]
|
|
mov edi, dword [rax + 12]
|
|
call print_u8 ; operand 1 size
|
|
call print_tab
|
|
|
|
mov rax, qword [rsp]
|
|
mov edi, dword [rax + 16]
|
|
call print_u8 ; encoding
|
|
call print_tab
|
|
|
|
mov rax, qword [rsp]
|
|
mov edi, dword [rax + 20]
|
|
call print_u32 ; opcode
|
|
call print_tab
|
|
|
|
mov rax, qword [rsp]
|
|
mov edi, dword [rax + 24]
|
|
call print_u8 ; rm-bits
|
|
call print_tab
|
|
|
|
mov rax, qword [rsp]
|
|
mov edi, dword [rax + 28]
|
|
call print_u8 ; prefix
|
|
|
|
call print_nl
|
|
|
|
add rsp, 8
|
|
ret
|
|
|
|
print_op_table:
|
|
push rbx
|
|
xor ebx, ebx
|
|
.loop:
|
|
cmp ebx, 241
|
|
jge .done
|
|
|
|
mov rdi, rbx
|
|
call op_table_entry_print
|
|
inc ebx
|
|
jmp .loop
|
|
|
|
.done:
|
|
pop rbx
|
|
ret
|
|
|
|
;; rdi: *u8
|
|
strlen:
|
|
xor rax, rax
|
|
.strlen_loop:
|
|
cmp byte [rdi + rax], 0
|
|
je .strlen_done
|
|
inc rax
|
|
jmp .strlen_loop
|
|
.strlen_done:
|
|
ret
|
|
|
|
;; lhs: (rdi, rsi)
|
|
;; rhs: (rdx, rcx)
|
|
;; al
|
|
strcmp:
|
|
cmp rcx, rsi
|
|
cmovb rsi, rcx ; if rhs is shorter, use its length for the loop
|
|
xor eax, eax
|
|
.strcmp_loop:
|
|
cmp rsi, rax
|
|
jz .strcmp_equal
|
|
movzx ecx, byte [rdx + rax]
|
|
cmp byte [rdi + rax], cl
|
|
lea rax, [rax + 1]
|
|
je .strcmp_loop
|
|
seta al ; al = lhs > rhs
|
|
sbb al, 0 ; al = al - CF
|
|
ret
|
|
.strcmp_equal:
|
|
xor eax, eax
|
|
ret
|
|
|
|
;; find the first occurrence of $dl in the first $rsi bytes of $rdi
|
|
strfind:
|
|
xor eax, eax
|
|
.loop:
|
|
cmp rax, rsi
|
|
jge .not_found
|
|
mov cl, byte [rdi + rax]
|
|
cmp cl, dl
|
|
je .found
|
|
inc rax
|
|
jmp .loop
|
|
.not_found:
|
|
mov rax, -1
|
|
.found:
|
|
ret
|
|
|
|
;; rdi: src
|
|
;; rsi: dst
|
|
;; rdx: len
|
|
memcpy:
|
|
.loop:
|
|
test rdx, rdx
|
|
jz .done
|
|
mov al, byte [rdi]
|
|
mov byte [rsi], al
|
|
inc rsi
|
|
inc rdi
|
|
dec rdx
|
|
jmp .loop
|
|
.done:
|
|
ret
|
|
|
|
is_alpha:
|
|
movzx eax, dil
|
|
and eax, 0x1fffdf ; ignore bit 5 (case)
|
|
add eax, -65 ; subtract 'A'
|
|
cmp eax, 26 ; check if in range 0-25
|
|
setb al
|
|
ret
|
|
|
|
is_digit:
|
|
movzx edi, dil
|
|
lea eax, [rdi - 48] ; subtract '0'
|
|
cmp eax, 10 ; check if in range 0-9
|
|
setb al
|
|
ret
|
|
|
|
exit:
|
|
mov rax, 60
|
|
syscall
|
|
|
|
|
|
;; Operands
|
|
|
|
%define KIND_NONE 0
|
|
%define KIND_REG 1
|
|
%define KIND_MEM 2
|
|
%define KIND_IMM 3
|
|
|
|
struc operand
|
|
.type resd 1
|
|
.size resd 1
|
|
.reg resb 1
|
|
.index resb 1
|
|
.scale resb 1
|
|
.pad resb 1
|
|
.disp resd 1
|
|
endstruc
|
|
|
|
struc operand_imm
|
|
.type resd 1
|
|
.size resd 1
|
|
.imm resq 1
|
|
endstruc
|
|
|
|
abcd_reg_indices: db 0, 3, 1, 2
|
|
rX_suffixes: db 'b', 'w', 'd'
|
|
|
|
global try_parse_reg
|
|
try_parse_reg:
|
|
push rbx ; buf
|
|
push r12 ; reg_num
|
|
push r13 ; size
|
|
xor r12d, r12d
|
|
xor r13d, r13d
|
|
|
|
lea rbx, [rel buf]
|
|
mov dil, byte [rbx]
|
|
call is_alpha
|
|
jnb .done
|
|
cmp dil, 'r'
|
|
jne .not_64_or_rX
|
|
|
|
inc rbx
|
|
mov dil, byte [rbx]
|
|
call is_digit
|
|
jnb .not_rX
|
|
|
|
inc rbx
|
|
sub dil, '0'
|
|
movzx r12d, dil
|
|
cmp dil, 1
|
|
jne .rX_size
|
|
|
|
shl r12d, 3
|
|
lea r12d, [r12d + edi * 2] ; * 10
|
|
movzx edi, byte [rbx]
|
|
sub edi, '0'
|
|
add r12d, edi ; * 10 + digit
|
|
|
|
inc rbx
|
|
|
|
.rX_size:
|
|
lea rdi, [rel rX_suffixes]
|
|
mov rsi, 3
|
|
mov dl, byte [rbx]
|
|
call strfind
|
|
cmp rax, 0
|
|
mov r13d, eax
|
|
mov edi, 3
|
|
cmovl r13d, edi
|
|
jmp .done
|
|
|
|
.not_rX:
|
|
mov r13d, 3 ; 64-bit register
|
|
.r_or_e:
|
|
|
|
mov dx, word [rbx]
|
|
add rbx, 2
|
|
|
|
mov r12d, 4 ; rsp
|
|
cmp dx, 'sp'
|
|
je .done
|
|
|
|
mov r12d, 5 ; rbp
|
|
cmp dx, 'bp'
|
|
je .done
|
|
|
|
mov r12d, 6 ; rsi
|
|
cmp dx, 'si'
|
|
je .done
|
|
|
|
mov r12d, 7 ; rdi
|
|
cmp dx, 'di'
|
|
je .done
|
|
|
|
mov r12d, -1 ; rip
|
|
cmp dx, 'ip'
|
|
je .done
|
|
|
|
lea rax, [rel abcd_reg_indices]
|
|
sub dl, 'a'
|
|
movzx edx, dl
|
|
movzx r12d, byte [rax + rdx] ; rax, rcx, rdx, rbx
|
|
|
|
.done:
|
|
mov rax, rbx
|
|
lea rbx, [rel buf]
|
|
sub rax, rbx ; number of bytes consumed
|
|
|
|
movzx rdx, r12d ; reg_num
|
|
shl rdx, 32
|
|
mov r12d, r13d ; size
|
|
or rdx, r12
|
|
|
|
pop r13
|
|
pop r12
|
|
pop rbx
|
|
ret
|
|
|
|
.not_64_or_rX:
|
|
cmp dil, 'e'
|
|
jne .not_32
|
|
mov r13d, 2 ; 32-bit register
|
|
inc rbx
|
|
jmp .r_or_e
|
|
|
|
.not_32:
|
|
xor ecx, ecx
|
|
|
|
cmp byte [rbx + 1], 'l'
|
|
sete al
|
|
cmp byte [rbx + 2], 'l'
|
|
sete cl
|
|
xor al, cl
|
|
mov r13d, 1
|
|
sub r13d, eax
|
|
jmp .r_or_e
|
|
|
|
global _entry_print_table
|
|
_entry_print_table:
|
|
call print_op_table
|
|
call exit
|