All pastes #1390813 Raw Edit

Something

public cpp v1 · immutable
#1390813 ·published 2009-04-13 18:24 UTC
rendered paste body
// No 16 bit addressing because it's a pain and obsolete.// Segment selection unfortunately isn't obsolete, but it's still a pain.#include <assert.h>typedef unsigned char u8;typedef unsigned short u16;typedef unsigned long u32;typedef unsigned long long u64;typedef char s8;typedef short s16;typedef long s32;typedef long long s64;#define TLS __declspec(thread)#define OPNAME(op) x##op#define OP1(op, b1) struct x86##op : b1 { using b1::operator(); }; \	const x86##op OPNAME(op);#define OP2(op, b1, b2) struct x86##op : b1, b2 { \	using b1::operator(); using b2::operator(); }; \	const x86##op OPNAME(op);#include <stdio.h>// internals all prefixed with x86 because I'm paranoid like thatnamespace X86 {	TLS u8 *x86Ptr;	struct x86Reg {		int type;		int n;		inline bool operator==(const x86Reg& reg) const		{			return type == reg.type && n == reg.n;		}	};	const int x86RegWidth[6] = {8, 16, 32, 64, 64, 128};	const x86Reg x86NoReg = {-1, -1};	const x86Reg al = {0, 0}, cl = {0, 1}, dl = {0, 2}, bl = {0, 3},		ah = {0, 4}, ch = {0, 5}, dh = {0, 6}, bh = {0, 7};	const x86Reg ax = {1, 0}, cx = {1, 1}, dx = {1, 2}, bx = {1, 3},		sp = {1, 4}, bp = {1, 5}, si = {1, 6}, di = {1, 7};	const x86Reg eax = {2, 0}, ecx = {2, 1}, edx = {2, 2}, ebx = {2, 3},		esp = {2, 4}, ebp = {2, 5}, esi = {2, 6}, edi = {2, 7};	const x86Reg rax = {3, 0}, rcx = {3, 1}, rdx = {3, 2}, rbx = {3, 3},		rsp = {3, 4}, rbp = {3, 5}, rsi = {3, 6}, rdi = {3, 7},		r8 = {3, 8}, r9 = {3, 9}, r10 = {3, 10}, r11 = {3, 11},		r12 = {3, 12}, r13 = {3, 13}, r14 = {3, 14}, r15 = {3, 15};	const x86Reg st0 = {4, 0}, st1 = {4, 1}, st2 = {4, 2}, st3 = {4, 3},		st4 = {4, 4}, st5 = {4, 5}, st6 = {4, 6}, st7 = {4, 7};	const x86Reg mm0 = {4, 0}, mm1 = {4, 1}, mm2 = {4, 2}, mm3 = {4, 3},		mm4 = {4, 4}, mm5 = {4, 5}, mm6 = {4, 6}, mm7 = {4, 7};	const x86Reg xmm0 = {5, 0}, xmm1 = {5, 1}, xmm2 = {5, 2}, xmm3 = {5, 3},		xmm4 = {5, 4}, xmm5 = {5, 5}, xmm6 = {5, 6}, xmm7 = {5, 7};	// an intermediate class converted to an effective address with *ptr[]	struct x86RegMaths {		x86Reg base;		x86Reg index;		int scale;		s32 disp;	};}inline const X86::x86RegMaths operator*(const X86::x86Reg &r, int s){	const X86::x86RegMaths ret = {X86::x86NoReg, r, s, 0};	return ret;}inline const X86::x86RegMaths operator+(const X86::x86Reg &r, s32 disp){	const X86::x86RegMaths ret = {r, X86::x86NoReg, 0, disp};	return ret;}inline const X86::x86RegMaths operator+(const X86::x86RegMaths &rm, s32 disp){	const X86::x86RegMaths ret = {rm.base, rm.index, rm.scale, rm.disp + disp};	return ret;}inline const X86::x86RegMaths operator+(const X86::x86RegMaths &rm, const X86::x86Reg &r){	if (rm.base == X86::x86NoReg) {		const X86::x86RegMaths ret = {r, rm.index, rm.scale, rm.disp};		return ret;	} else if (r == rm.base && rm.index == X86::x86NoReg) {		const X86::x86RegMaths ret = {X86::x86NoReg, r, 2, rm.disp};		return ret;	}}namespace X86 {	struct x86EAddr {		int width;		struct x86RegMaths rm;	};	template<int width> class x86EAddrFactory {		x86EAddr operator[](const x86RegMaths &rm)		{			const x86EAddr ret = {width, {rm.base, rm.index, rm.scale, rm.disp}};			return ret;		}		x86EAddr operator[](const x86Reg &reg)		{			const x86EAddr ret = {width, {reg, x86NoReg, 0, 0}};			return ret;		}		template<typename T> x86EAddr operator[](T *p)		{			const x86EAddr ret = {width, {x86NoReg, x86NoReg, 0, (s32)p}};			return ret;		}	};	x86EAddrFactory<0> ptr;	x86EAddrFactory<8> ptr8, byteptr;	x86EAddrFactory<16> ptr16, wordptr;	x86EAddrFactory<32> ptr32, dwordptr;	x86EAddrFactory<64> ptr64, qwordptr, mmwordptr;	x86EAddrFactory<128> ptr128, xmmwordptr;	void x86Write8(u8 b)	{		*x86Ptr++ = b;	}	void x86Write16(u16 w)	{		*(u16*)x86Ptr = w;		x86Ptr += 2;	}	void x86Write32(u32 dw)	{		*(u32*)x86Ptr = dw;		x86Ptr += 4;	}	void x86Write64(u64 qw)	{		*(u64*)x86Ptr = qw;		x86Ptr += 8;	}	// Left to right opcode helper for readability	void x86WriteOp(u32 opcode)	{		if (opcode >> 24)			x86Write32(opcode);		else {			if (opcode >> 16)				x86Write8((opcode >> 16) & 0xffU);			if (opcode >> 8)				x86Write8((opcode >> 8) & 0xffU);			x86Write8(opcode & 0xffU);		}	}	void x86WriteModRM(x86Reg rm, int reg)	{		/* TODO */	}	void x86WriteModRM(x86EAddr rm, int reg)	{		/* TODO */	}	template<u32 opcode> struct x86Naked	{		void operator()() const		{			x86WriteOp(opcode);		}	};	template<u32 opcode> struct x86Imm8	{		void operator()(u8 ib) const		{			x86WriteOp(opcode);			x86Write8(ib);		}	};	template<u32 opcode> struct x86Imm16	{		void operator()(u16 iw) const		{			x86WriteOp(opcode);			x86Write16(iw);		}	};	template<u32 opcode, u8 reg, u32 opA> struct x86Rm_ImmSW	{		void operator()(x86EAddr x, s32 y) const		{			int signext = (s8)(u8)y == y;			if (EAX == x) {				x86WriteOp(opA | signext);				x86WriteModRM(x, reg);			} else {				x86WriteOp(opcode | signext);				x86WriteModRM(x, reg);			}			if (signext)				x86Write8((u8)y);			else				x86Write32((u32)y);		}	};	template<u32 opcode> struct x86Rm_RmW	{	private:		__forceinline void write(const x86Reg &rm, const x86Reg &reg, int w, int dir) const {			x86WriteOp(opcode | (w >= 16 ? 1 : 0) | (dir ? 2 : 0));		}		__forceinline void write(const x86EAddr &rm, const x86Reg &reg, int w, int dir) const {			x86WriteOp(opcode | (w >= 16 ? 1 : 0) | (dir ? 2 : 0));		}	public:		__forceinline void operator()(const x86Reg &x, const x86Reg &y) const		{			assert(x.type == y.type);			write(x, y, x86RegWidth[x.type], 0);		}		__forceinline void operator()(const x86EAddr &x, const x86Reg &y) const		{			assert(x86RegWidth[y.type] == x.width);			write(x, y, x.width, 0);		}		template<int w> __forceinline void operator()(const x86Reg &x, const x86EAddr &y) const		{			assert(x86RegWidth[x.type] == y.width);			write(y, x, y.width, 1);		}	};// ugh#define _ ,	namespace X86_32 {		OP1(AAA, x86Naked<0x37>);		OP2(AAD, x86Naked<0xD50A>, x86Imm8<0xD5>);		OP2(AAM, x86Naked<0xD40A>, x86Imm8<0xD4>);		OP1(AAS, x86Naked<0x3F>);	};	namespace X86_3264 {		OP2(RET, x86Naked<0xC3>, x86Imm16<0xC2>);		OP2(RETF, x86Naked<0xCB>, x86Imm16<0xCA>);		OP2(ADC, x86Rm_ImmSW<0x80 _ 2 _ 0x14>, x86Rm_RmW<0x10>);	};	// import after X86_3264	namespace X86_64 {		// OP2(ADC	};#undef _};using namespace X86;using namespace X86::X86_3264;using namespace X86::X86_32;using namespace X86::X86_64;#include <stdlib.h>#include <stdio.h>int main(){	u8* buf = static_cast<u8*>(malloc(0x40000));	x86Ptr = buf;	xRET();	xAAA();	xAAD();	xAAD(16);	xAAM();	xAAM(16);	xAAS();	xADC(eax, edx);	xADC(dwordptr[buf], eax);	xRET();	xRET(16);	xRETF();	xRETF(20);	((void(*)())buf)();	return 0;}