#ifndef _library__assembler_intrinsics_i386__hpp__included__ #define _library__assembler_intrinsics_i386__hpp__included__ #include "assembler.hpp" #include #include namespace assembler_intrinsics { struct I386 { struct ref; struct sib_scale_off_intermediate; struct sib_scale_intermediate; struct reg { explicit reg(uint8_t _val); ref operator[](int32_t off) const; sib_scale_intermediate operator*(uint8_t scale) const; ref operator[](const reg r) const; ref operator[](sib_scale_intermediate r) const; ref operator[](sib_scale_off_intermediate r) const; sib_scale_off_intermediate operator+(int32_t off) const; bool hbit(); uint8_t lbits(); uint8_t num(); bool valid(bool amd64); bool is_none(); private: friend class ref; friend class sib_scale_intermediate; friend class sib_scale_off_intermediate; uint8_t val; }; const static reg reg_none; const static reg reg_ax; const static reg reg_bx; const static reg reg_cx; const static reg reg_dx; const static reg reg_bp; //Don't use in 8-bit mode. const static reg reg_sp; //Don't use in 8-bit mode. const static reg reg_si; //Don't use in 8-bit mode. const static reg reg_di; //Don't use in 8-bit mode. const static reg reg_r8; const static reg reg_r9; const static reg reg_r10; const static reg reg_r11; const static reg reg_r12; const static reg reg_r13; const static reg reg_r14; const static reg reg_r15; const static reg reg_rip; struct sib_scale_off_intermediate { sib_scale_off_intermediate(reg idx, uint8_t scale, int32_t offset); private: friend class reg; friend class ref; reg index; uint8_t scale; int32_t offset; }; struct sib_scale_intermediate { sib_scale_intermediate(reg idx, uint8_t scale); sib_scale_off_intermediate operator+(int32_t off) const; private: friend class reg; friend class ref; reg index; uint8_t scale; }; struct low { low(bool _need_amd64, uint8_t _rex_prefix, std::vector _ref); bool need_amd64(); bool has_rex(); uint8_t rex_prefix(); std::vector bytes(); void emit_rex(assembler::assembler& a); void emit_bytes(assembler::assembler& a); private: bool needs_amd64; uint8_t rex; std::vector mref; }; struct ref { ref(); ref(reg r); ref(sib_scale_intermediate r); ref(sib_scale_off_intermediate r); low operator()(reg r, bool set_size_flag, bool amd64); void emit(assembler::assembler& a, bool set_size_flag, bool amd64, reg r, uint8_t op1); void emit(assembler::assembler& a, bool set_size_flag, bool amd64, reg r, uint8_t op1, uint8_t op2); private: friend class sib_scale_intermediate; friend class sib_scale_off_intermediate; friend class reg; static ref reg_off(reg r, int32_t off = 0); static ref rip_off(int32_t off = 0); static ref sib(reg base, reg index, uint8_t scale = 1, int32_t off = 0); bool needs_amd64; uint8_t rex; std::vector mref; }; I386(assembler::assembler& _a, bool _amd64); //Is amd64? bool is_amd64(); //Is i386? bool is_i386(); //Get word size. uint8_t wordsize(); //Label: void label(assembler::label& l); //PUSH NWORD void push_reg(reg r); //POP NWORD void pop_reg(reg r); //MOV NWORD , void mov_reg_regmem(reg r, ref mem); //LEA , void lea_reg_mem(reg r, ref mem); //XOR NWORD , void xor_reg_regmem(reg r, ref mem); //MOV BYTE , imm void mov_regmem_imm8(ref mem, uint8_t imm); //ADD BYTE , imm void add_regmem_imm8(ref mem, uint8_t imm); //MOV DWORD , imm void mov_regmem_imm32(ref mem, uint32_t imm); //MOV WORD , void mov_regmem_reg16(ref mem, reg r); //MOV WORD , void mov_reg_regmem16(reg r, ref mem); //MOV BYTE , void mov_reg_regmem8(reg r, ref mem); //MOV BYTE , void mov_regmem_reg8(ref mem, reg r); //OR BYTE , imm void or_regmem_imm8(ref mem, uint8_t imm); //AND BYTE , imm void and_regmem_imm8(ref mem, uint8_t imm); //TEST BYTE , imm void test_regmem_imm8(ref mem, uint8_t imm); //CMP BYTE , imm void cmp_regmem_imm8(ref mem, uint8_t imm); //CMP NWORD , imm void cmp_regmem_imm(ref mem, int32_t imm); //SHL NWORD , imm void shl_regmem_imm(ref mem, uint8_t imm); //SHL BYTE , imm void shl_regmem_imm8(ref mem, uint8_t imm); //AND NWORD , imm void and_regmem_imm(ref mem, int32_t imm); //ADD NWORD , imm void add_regmem_imm(ref mem, int32_t imm); //ADD NWORD , void add_reg_regmem(reg r, ref mem); //INC NWORD void inc_regmem(ref mem); //MOV NWORD , . void mov_reg_addr(reg r, assembler::label& l); //MOV NWORD , imm. void mov_reg_imm(reg r, size_t imm); //NEG BYTE void neg_regmem8(ref mem); //OR BYTE , void or_regmem_reg8(ref mem, reg r); //CALL void call_addr(assembler::label& l); //CALL void call_regmem(ref mem); //SETNZ void setnz_regmem(ref mem); //JMP void jmp_regmem(ref mem); //JNZ SHORT