forsyth20121205-174063a80cc13 years agoHistory
1630 lines · 30.1 KB · C
RawDownload
#include <lib9.h>#include <kernel.h> int	i386inst(ulong, char, char*, int);int	i386das(ulong, char*, int);int	i386instlen(ulong); static uchar *dasdata; static char *_hexify(char *buf, ulong p, int zeros){	ulong d; 	d = p/16;	if(d)		buf = _hexify(buf, d, zeros-1);	else		while(zeros--)			*buf++ = '0';	*buf++ = "0123456789abcdef"[p&0x0f];	return buf;} /* *  an instruction */typedef struct Instr Instr;struct	Instr{	uchar	mem[1+1+1+1+2+1+1+4+4];		/* raw instruction */	ulong	addr;		/* address of start of instruction */	int	n;		/* number of bytes in instruction */	char	*prefix;	/* instr prefix */	char	*segment;	/* segment override */	uchar	jumptype;	/* set to the operand type for jump/ret/call */	char	osize;		/* 'W' or 'L' */	char	asize;		/* address size 'W' or 'L' */	uchar	mod;		/* bits 6-7 of mod r/m field */	uchar	reg;		/* bits 3-5 of mod r/m field */	char	ss;		/* bits 6-7 of SIB */	char	index;		/* bits 3-5 of SIB */	char	base;		/* bits 0-2 of SIB */	short	seg;		/* segment of far address */	ulong	disp;		/* displacement */	ulong 	imm;		/* immediate */	ulong 	imm2;		/* second immediate operand */	char	*curr;		/* fill level in output buffer */	char	*end;		/* end of output buffer */	char	*err;		/* error message */}; 	/* 386 register (ha!) set */enum{	AX=0,	CX,	DX,	BX,	SP,	BP,	SI,	DI,};	/* Operand Format codes *//*%A	-	address size register modifier (!asize -> 'E')%C	-	Control register CR0/CR1/CR2%D	-	Debug register DR0/DR1/DR2/DR3/DR6/DR7%I	-	second immediate operand%O	-	Operand size register modifier (!osize -> 'E')%T	-	Test register TR6/TR7%S	-	size code ('W' or 'L')%X	-	Weird opcode: OSIZE == 'W' => "CBW"; else => "CWDE"%d	-	displacement 16-32 bits%e	-	effective address - Mod R/M value%f	-	floating point register F0-F7 - from Mod R/M register%g	-	segment register%i	-	immediate operand 8-32 bits%p	-	PC-relative - signed displacement in immediate field%r	-	Reg from Mod R/M%x	-	Weird opcode: OSIZE == 'W' => "CWD"; else => "CDQ"*/ typedef struct Optable Optable;struct Optable{	char	operand[2];	void	*proto;		/* actually either (char*) or (Optable*) */};	/* Operand decoding codes */enum {	Ib = 1,			/* 8-bit immediate - (no sign extension)*/	Ibs,			/* 8-bit immediate (sign extended) */	Jbs,			/* 8-bit sign-extended immediate in jump or call */	Iw,			/* 16-bit immediate -> imm */	Iw2,			/* 16-bit immediate -> imm2 */	Iwd,			/* Operand-sized immediate (no sign extension)*/	Awd,			/* Address offset */	Iwds,			/* Operand-sized immediate (sign extended) */	RM,			/* Word or long R/M field with register (/r) */	RMB,			/* Byte R/M field with register (/r) */	RMOP,			/* Word or long R/M field with op code (/digit) */	RMOPB,			/* Byte R/M field with op code (/digit) */	RMR,			/* R/M register only (mod = 11) */	RMM,			/* R/M memory only (mod = 0/1/2) */	R0,			/* Base reg of Mod R/M is literal 0x00 */	R1,			/* Base reg of Mod R/M is literal 0x01 */	FRMOP,			/* Floating point R/M field with opcode */	FRMEX,			/* Extended floating point R/M field with opcode */	JUMP,			/* Jump or Call flag - no operand */	RET,			/* Return flag - no operand */	OA,			/* literal 0x0a byte */	PTR,			/* Seg:Displacement addr (ptr16:16 or ptr16:32) */	AUX,			/* Multi-byte op code - Auxiliary table */	PRE,			/* Instr Prefix */	SEG,			/* Segment Prefix */	OPOVER,			/* Operand size override */	ADDOVER,		/* Address size override */};	static Optable optab0F00[8]={	0,0,		"MOVW	LDT,%e",	0,0,		"MOVW	TR,%e",	0,0,		"MOVW	%e,LDT",	0,0,		"MOVW	%e,TR",	0,0,		"VERR	%e",	0,0,		"VERW	%e",}; static Optable optab0F01[8]={	0,0,		"MOVL	GDTR,%e",	0,0,		"MOVL	IDTR,%e",	0,0,		"MOVL	%e,GDTR",	0,0,		"MOVL	%e,IDTR",	0,0,		"MOVW	MSW,%e",	/* word */	0,0,		nil,	0,0,		"MOVW	%e,MSW",	/* word */}; static Optable optab0FBA[8]={	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	Ib,0,		"BT%S	%i,%e",	Ib,0,		"BTS%S	%i,%e",	Ib,0,		"BTR%S	%i,%e",	Ib,0,		"BTC%S	%i,%e",}; static Optable optab0F[256]={	RMOP,0,		optab0F00,	RMOP,0,		optab0F01,	RM,0,		"LAR	%e,%r",	RM,0,		"LSL	%e,%r",	0,0,		nil,	0,0,		nil,	0,0,		"CLTS",	0,0,		nil,	0,0,		"INVD",	0,0,		"WBINVD",	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil, 	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil, 	RMR,0,		"MOVL	%C,%e",		/* [0x20] */	RMR,0,		"MOVL	%D,%e",	RMR,0,		"MOVL	%e,%C",	RMR,0,		"MOVL	%e,%D",	RMR,0,		"MOVL	%T,%e",	0,0,		nil,	RMR,0,		"MOVL	%e,%T",	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil, 	0,0,		"WRMSR",		/* [0x30] */	0,0,		"RDTSC",	0,0,		"RDMSR",	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil, 	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil, 	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil, 	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil, 	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil,	0,0,		nil, 	Iwds,0,		"JOS	%p",	/* [0x80] */	Iwds,0,		"JOC	%p",	Iwds,0,		"JCS	%p",	Iwds,0,		"JCC	%p",	Iwds,0,		"JEQ	%p",	Iwds,0,		"JNE	%p",	Iwds,0,		"JLS	%p",	Iwds,0,		"JHI	%p",	Iwds,0,		"JMI	%p",	Iwds,0,		"JPL	%p",	Iwds,0,		"JPS	%p",	Iwds,0,		"JPC	%p",	Iwds,0,		"JLT	%p",	Iwds,0,		"JGE	%p",	Iwds,0,		"JLE	%p",	Iwds,0,		"JGT	%p", 	RMB,0,		"SETOS	%e",	/* [0x90] */	RMB,0,		"SETOC	%e",	RMB,0,		"SETCS	%e",	RMB,0,		"SETCC	%e",	RMB,0,		"SETEQ	%e",	RMB,0,		"SETNE	%e",	RMB,0,		"SETLS	%e",	RMB,0,		"SETHI	%e",	RMB,0,		"SETMI	%e",	RMB,0,		"SETPL	%e",	RMB,0,		"SETPS	%e",	RMB,0,		"SETPC	%e",	RMB,0,		"SETLT	%e",	RMB,0,		"SETGE	%e",	RMB,0,		"SETLE	%e",	RMB,0,		"SETGT	%e", 	0,0,		"PUSHL	FS",	/* [0xa0] */	0,0,		"POPL	FS",	0,0,		"CPUID",	RM,0,		"BT%S	%r,%e",	RM,Ib,		"SHLD%S	%r,%i,%e",	RM,0,		"SHLD%S	%r,CL,%e",	0,0,		nil,	0,0,		nil,	0,0,		"PUSHL	GS",	0,0,		"POPL	GS",	0,0,		nil,	RM,0,		"BTS%S	%r,%e",	RM,Ib,		"SHRD%S	%r,%i,%e",	RM,0,		"SHRD%S	%r,CL,%e",	0,0,		nil,	RM,0,		"IMUL%S	%e,%r", 	0,0,		nil,	0,0,		nil,	RMM,0,		"LSS	%e,%r",	/* [0xb2] */	RM,0,		"BTR%S	%r,%e",	RMM,0,		"LFS	%e,%r",	RMM,0,		"LGS	%e,%r",	RMB,0,		"MOVBZX	%e,%R",	RM,0,		"MOVWZX	%e,%R",	0,0,		nil,	0,0,		nil,	RMOP,0,		optab0FBA,	RM,0,		"BTC%S	%e,%r",	RM,0,		"BSF%S	%e,%r",	RM,0,		"BSR%S	%e,%r",	RMB,0,		"MOVBSX	%e,%R",	RM,0,		"MOVWSX	%e,%R",}; static Optable optab80[8]={	Ib,0,		"ADDB	%i,%e",	Ib,0,		"ORB	%i,%e",	Ib,0,		"ADCB	%i,%e",	Ib,0,		"SBBB	%i,%e",	Ib,0,		"ANDB	%i,%e",	Ib,0,		"SUBB	%i,%e",	Ib,0,		"XORB	%i,%e",	Ib,0,		"CMPB	%e,%i",}; static Optable optab81[8]={	Iwd,0,		"ADD%S	%i,%e",	Iwd,0,		"OR%S	%i,%e",	Iwd,0,		"ADC%S	%i,%e",	Iwd,0,		"SBB%S	%i,%e",	Iwd,0,		"AND%S	%i,%e",	Iwd,0,		"SUB%S	%i,%e",	Iwd,0,		"XOR%S	%i,%e",	Iwd,0,		"CMP%S	%e,%i",}; static Optable optab83[8]={	Ibs,0,		"ADD%S	%i,%e",	Ibs,0,		"OR%S	%i,%e",	Ibs,0,		"ADC%S	%i,%e",	Ibs,0,		"SBB%S	%i,%e",	Ibs,0,		"AND%S	%i,%e",	Ibs,0,		"SUB%S	%i,%e",	Ibs,0,		"XOR%S	%i,%e",	Ibs,0,		"CMP%S	%e,%i",}; static Optable optabC0[8] ={	Ib,0,		"ROLB	%i,%e",	Ib,0,		"RORB	%i,%e",	Ib,0,		"RCLB	%i,%e",	Ib,0,		"RCRB	%i,%e",	Ib,0,		"SHLB	%i,%e",	Ib,0,		"SHRB	%i,%e",	0,0,		nil,	Ib,0,		"SARB	%i,%e",}; static Optable optabC1[8] ={	Ib,0,		"ROL%S	%i,%e",	Ib,0,		"ROR%S	%i,%e",	Ib,0,		"RCL%S	%i,%e",	Ib,0,		"RCR%S	%i,%e",	Ib,0,		"SHL%S	%i,%e",	Ib,0,		"SHR%S	%i,%e",	0,0,		nil,	Ib,0,		"SAR%S	%i,%e",}; static Optable optabD0[8] ={	0,0,		"ROLB	%e",	0,0,		"RORB	%e",	0,0,		"RCLB	%e",	0,0,		"RCRB	%e",	0,0,		"SHLB	%e",	0,0,		"SHRB	%e",	0,0,		nil,	0,0,		"SARB	%e",}; static Optable optabD1[8] ={	0,0,		"ROL%S	%e",	0,0,		"ROR%S	%e",	0,0,		"RCL%S	%e",	0,0,		"RCR%S	%e",	0,0,		"SHL%S	%e",	0,0,		"SHR%S	%e",	0,0,		nil,	0,0,		"SAR%S	%e",}; static Optable optabD2[8] ={	0,0,		"ROLB	CL,%e",	0,0,		"RORB	CL,%e",	0,0,		"RCLB	CL,%e",	0,0,		"RCRB	CL,%e",	0,0,		"SHLB	CL,%e",	0,0,		"SHRB	CL,%e",	0,0,		nil,	0,0,		"SARB	CL,%e",}; static Optable optabD3[8] ={	0,0,		"ROL%S	CL,%e",	0,0,		"ROR%S	CL,%e",	0,0,		"RCL%S	CL,%e",	0,0,		"RCR%S	CL,%e",	0,0,		"SHL%S	CL,%e",	0,0,		"SHR%S	CL,%e",	0,0,		nil,	0,0,		"SAR%S	CL,%e",}; static Optable optabD8[8+8] ={	0,0,		"FADDF	%e,F0",	0,0,		"FMULF	%e,F0",	0,0,		"FCOMF	%e,F0",	0,0,		"FCOMFP	%e,F0",	0,0,		"FSUBF	%e,F0",	0,0,		"FSUBRF	%e,F0",	0,0,		"FDIVF	%e,F0",	0,0,		"FDIVRF	%e,F0",	0,0,		"FADDD	%f,F0",	0,0,		"FMULD	%f,F0",	0,0,		"FCOMD	%f,F0",	0,0,		"FCOMPD	%f,F0",	0,0,		"FSUBD	%f,F0",	0,0,		"FSUBRD	%f,F0",	0,0,		"FDIVD	%f,F0",	0,0,		"FDIVRD	%f,F0",};/* *	optabD9 and optabDB use the following encoding:  *	if (0 <= modrm <= 2) instruction = optabDx[modrm&0x07]; *	else instruction = optabDx[(modrm&0x3f)+8]; * *	the instructions for MOD == 3, follow the 8 instructions *	for the other MOD values stored at the front of the table. */static Optable optabD9[64+8] ={	0,0,		"FMOVF	%e,F0",	0,0,		nil,	0,0,		"FMOVF	F0,%e",

Lines 1–500 of 1630.