#ifndef _ASM_H #define _ASM_H #include #include typedef size_t ip; extern ip here; // A general-purpose x86 register. // The specific register size (e.g. al/ax/eax/rax) depends on the instruction. // All registers are valid for all instructions; we will perform exchanges if necessary. typedef enum reg { RA = 0, // rax, eax, ax, al RC = 1, // rcx, ecx, cx, cl RD = 2, // rdx, edx, dx, dl RB = 3, // rbx, ebx, bx, bl SP = 4, // rsp, esp, sp, spl (we do not use ah) BP = 5, // rbp, ebp, bp, bpl (we do not use ch) SI = 6, // rsi, esi, si, sil (we do not use dh) DI = 7, // rdi, edi, di, dil (we do not use bh) R8 = 8, // r8, r8d, r8w, r8l R9 = 9, // r9, r9d, r9w, r9l R10 = 10, // r10, r10d, r10w, r10l R11 = 11, // r11, r11d, r11w, r11l R12 = 12, // r12, r12d, r12w, r12l R13 = 13, // r13, r13d, r13w, r13l R14 = 14, // r14, r14d, r14w, r14l R15 = 15, // r15, r15d, r15w, r15l } reg; /// Jump to a known address. void inst_jump(ip there); /// Jump to an unresolved address. ip inst_jump_unresolved(void); void inst_jump_resolve(ip disp, ip there); void inst_mov_imm(reg reg, uint64_t imm); void inst_mov_imm_i64(reg reg, int64_t imm); void inst_syscall(void); void inst_push(reg reg); void inst_pop(reg reg); void inst_mov(reg dest, reg src); void inst_mov_from(reg dest, reg base); void inst_mov_from_disp(reg dest, reg base, int32_t disp); void inst_mov_to(reg base, reg src); void inst_mov_to_disp(reg base, reg src, int32_t disp); #endif