File:  [MW Coherent from dump] / coherent / b / bin / db / i386 / i386db3.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:36 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * db/i386/i386db3.c
 * A debugger.
 * i386 disassembler tables for disassembler in i386/i386db2.c.
 * Intel operand order.
 */

#include "i386db.h"

/* 
 * Legend to characters following "%" tokens in strings,
 * taken from Intel i386 "Programmer's Reference Manual".
 *
 *	First char after '%'; see also 2nd char, general case below:
 *		A - direct address
 *		C - reg of r/m selects control register
 *		D - reg of r/m selects debug register
 *		E - modR/M selects operand
 *		F - flags register
 *		G - reg field of modR/M selects general register
 *		H - sign-extended immediate data (same as I but sign-extended)
 *		I - immediate data
 *		J - relative offset added to IP
 *		K - as J, except find symbol, if possible
 *		M - modR/M selects memory only
 *		O - no modR/M byte; offset only
 *		R - mod field of modR/M selects register only
 *		S - reg field of modR/M selects segment register
 *		T - reg feild of modR/M selects test register
 *		X - memory addressed by DS:ESI
 *		Y - memory addressed by ES:EDI
 *		Z - assembler instruction mnemonic size qualifier
 *		2 - prefix of two-byte opcode
 *
 *	For the following first characters after the %, the second after the %
 *	has a special meaning associated with it:
 *		e - put in 'e' if address size attribute = 32 
 *			- second char is part of reg name
 *		f - floating point 
 *			- second char is esc value
 *		g - REG/OPCODE field of the modR/M byte is interpreted as
 *		    additional opcode; it is used as an index to a
 *		    column in the 2-d group array (grp[][])
 *			- second character yields the group number, i.e., it 
 *			  is used as an index to a row in grp[][]  
 *		r - read next n bytes, but don't do anything with them; n is 
 *		    given by 2nd char and meaning conforms with general case
 *		s - size override:
 *			- second char has following meanings:
 *				"a" - address size override
 *				"o" - operand size override
 *
 *	Second char after '%', the general case:
 *		a - two words or dwords in memory (BOUND)
 *		b - byte
 *		d - dword
 *		f - 32 bit pointer
 *		l - 48 bit pointer
 *		p - 32 or 48 bit pointer
 *		s - six byte pseudo-descriptor
 *		v - word or dword
 *		w - word
 *		z - r/m16: append 'w' to assem. mnemonic
 *		  - r/m32: append 'w' to assem. mnemonic if operand size = 16,
 *			   append 'l' to assem. mnemonic if operand size = 32
 *		F - use floating regs in mod/rm (unused)
 *		1-8 - group number
 */

/******************************************************************************/

char *op_map_1[] = {
	/* 0 */
	"add%Zb %Eb,%Gb",    "add%Zv %Ev,%Gv",	  "add%Zb %Gb,%Eb",   "add%Zv %Gv,%Ev",
	"add%Zb al,%Ib",     "add%Zv %eax,%Iv",	  "push es",         "pop es",
	"or%Zb %Eb,%Gb",     "or%Zv %Ev,%Gv",	  "or%Zb %Gb,%Eb",    "or%Zv %Gv,%Ev",
	"or%Zb al,%Ib",      "or%Zv %eax,%Iv",	  "push cs",         "%2 ",

	/* 1 */
	"adc%Zb %Eb,%Gb",    "adc%Zv %Ev,%Gv",	  "adc%Zb %Gb,%Eb",   "adc%Zv %Gv,%Ev",
	"adc%Zb al,%Ib",     "adc%Zv %eax,%Iv",	  "push ss",	      "pop ss",
	"sbb%Zb %Eb,%Gb",    "sbb%Zv %Ev,%Gv",	  "sbb%Zb %Gb,%Eb",   "sbb%Zv %Gv,%Ev",
	"sbb%Zb al,%Ib",     "sbb%Zv %eax,%Iv",	  "push ds",	      "pop ds",

	/* 2 */
	"and%Zb %Eb,%Gb",    "and%Zv %Ev,%Gv",	  "and%Zb %Gb,%Eb",   "and%Zv %Gv,%Ev",
	"and%Zb al,%Ib",     "and%Zv %eax,%Iv",	  "es:",	      "daa",
	"sub%Zb %Eb,%Gb",    "sub%Zv %Ev,%Gv",	  "sub%Zb %Gb,%Eb",   "sub%Zv %Gv,%Ev",
	"sub%Zb al,%Ib",     "sub%Zv %eax,%Iv",	  "cs:",	      "das",

	/* 3 */
	"xor%Zb %Eb,%Gb",    "xor%Zv %Ev,%Gv",	  "xor%Zb %Gb,%Eb",   "xor%Zv %Gv,%Ev",
	"xor%Zb al,%Ib",     "xor%Zv %eax,%Iv",	  "ss:",	      "aaa",
	"cmp%Zb %Eb,%Gb",    "cmp%Zv %Ev,%Gv",	  "cmp%Zb %Gb,%Eb",   "cmp%Zv %Gv,%Ev",
	"cmp%Zb al,%Ib",     "cmp%Zv %eax,%Iv",	  "ds:",	      "aas",

	/* 4 */
	"inc%Zv %eax",       "inc%Zv %ecx",	  "inc%Zv %edx",      "inc%Zv %ebx",
	"inc%Zv %esp",       "inc%Zv %ebp",	  "inc%Zv %esi",      "inc%Zv %edi",
	"dec%Zv %eax",       "dec%Zv %ecx",	  "dec%Zv %edx",      "dec%Zv %ebx",
	"dec%Zv %esp",       "dec%Zv %ebp",	  "dec%Zv %esi",      "dec%Zv %edi",

	/* 5 */
	"push%Zv %eax",      "push%Zv %ecx",	  "push%Zv %edx",     "push%Zv %ebx",
	"push%Zv %esp",      "push%Zv %ebp",	  "push%Zv %esi",     "push%Zv %edi",
	"pop%Zv %eax",       "pop%Zv %ecx",	  "pop%Zv %edx",      "pop%Zv %ebx",
	"pop%Zv %esp",       "pop%Zv %ebp",	  "pop%Zv %esi",      "pop%Zv %edi",

	/* 6 */
	"pusha%Zv",          "popa%Zv",		  "bound%Zv %Gv,%Ma", "arpl %Ew,%Gw",
	"fs:",		     "gs:",		  "%so",	      "%sa",
	"push%Zv %Iv",     "imul%Zv %Gv,%Ev,%Iv", "push%Zb %Ib",      "imul%Zv %Gv,%Ev,%Hb",
	"ins%Zb %Yb",        "ins%Zv %Yv",	  "outs%Zb %Xb",      "outs%Zv %Xv",

	/* 7 */
	"jo %Jb",	     "jno %Jb",		  "jb %Jb",	       "jae %Jb",
	"je %Jb",	     "jne %Jb",		  "jbe %Jb",	       "ja %Jb",
	"js %Jb",	     "jns %Jb",		  "jp %Jb",	       "jnp %Jb",
	"jl %Jb",	     "jge %Jb",		  "jle %Jb",	       "jg %Jb",

	/* 8 */
	"%g1%Zb %Eb,%Ib",    "%g1%Zv %Ev,%Iv",	  "mov%Zb al,%Ib",     "%g1%Zv %Ev,%Hb",
	"test%Zb %Eb,%Gb",   "test%Zv %Ev,%Gv",	  "xchg%Zb %Eb,%Gb",   "xchg%Zv %Ev,%Gv",
	"mov%Zb %Eb,%Gb",    "mov%Zv %Ev,%Gv",	  "mov%Zb %Gb,%Eb",    "mov%Zv %Gv,%Ev",
	"mov%Zw %Ew,%Sw",    "lea%Zv %Gv,%M ",	  "mov%Zw %Sw,%Ew",    "pop%Zv %Ev",

	/* 9 */
	"nop",		     "xchg%Zv %eax,%ecx", "xchg%Zv %eax,%edx", "xchg%Zv %eax,%ebx",
	"xchg%Zv %eax,%esp", "xchg%Zv %eax,%ebp", "xchg%Zv %eax,%esi", "xchg%Zv %eax,%edi",
	"cbw",		     "cwd",		  "lcall %Ap",	       "fwait",
	"pushf%Zv",	     "popf%Zv",		  "sahf",	       "lahf",

	/* A */
	"mov%Zb al,%Ob",     "mov%Zv %eax,%Ov",	  "mov%Zb %Ob,al",     "mov%Zv %Ov,%eax",
	"movs%Zb %Xb%Yb",    "movs%Zz %Xv%Yv",	  "cmps%Zb %Xb%Yb",    "cmps%Zz %Xv%Yv",
	"test%Zb al,%Ib",    "test%Zv %eax,%Iv",  "stos%Zb %Yb",       "stos%Zz %Yv",
	"lods%Zb %Xb",	     "lods%Zz %Xv",	  "scas%Zb %Xb",       "scas%Zv %Xv",

	/* B */
	"mov%Zb al,%Ib",     "mov%Zb cl,%Ib",	  "mov%Zb dl,%Ib",     "mov%Zb bl,%Ib",
	"mov%Zb ah,%Ib",     "mov%Zb ch,%Ib",	  "mov%Zb dh,%Ib",     "mov%Zb bh,%Ib",
	"mov%Zv %eax,%Iv",   "mov%Zv %ecx,%Iv",	  "mov%Zv %edx,%Iv",   "mov%Zv %ebx,%Iv",
	"mov%Zv %esp,%Iv",   "mov%Zv %ebp,%Iv",	  "mov%Zv %esi,%Iv",   "mov%Zv %edi,%Iv",

	/* C */
	"%g2%Zb %Eb,%Ib",    "%g2%Zv %Ev,%Ib",	  "ret %Iw",	       "ret",
	"les%Zv %Gv,%Mp",    "lds%Zv %Gv,%Mp",	  "mov%Zb %Eb,%Ib",    "mov%Zv %Ev,%Iv",
	"enter %Iw,%Ib",     "leave",		  "lret %Iw",	       "lret",
	"int 3",	     "int %Ib",		  "into",	       "iret",

	/* D */
	"%g2%Zb %Eb,$1",     "%g2%Zv %Ev,$1",	  "%g2%Zb %Eb,cl",     "%g2%Zv %Ev,cl",
	"aam %rb",	     "aad %rb",		  NULL,		       "xlat",
	"%f0",		     "%f1",		  "%f2",	       "%f3",
	"%f4",		     "%f5",		  "%f6",	       "%f7",

	/* E */
	"loopne %Jb",	     "loope %Jb",	  "loop %Jb",	       "jcxz %Jb",
	"in%Zb %Ib",	     "in%Zv %Ib",	  "out%Zb %Ib,al",     "out%Zv %Ib,%eax",
	"call %Kv",	     "jmp %Jv",		  "ljmp %Ap",	       "jmp %Jb",
	"in%Zb ",	     "in%Zv ",		  "out%Zb dx,al",      "out%Zv dx,%eax",

	/* F */
	"lock",		     NULL,		  "repne",	       "rep",
	"hlt",		     "cmc",		  "%g3",	       "%g0",
	"clc",		     "stc",		  "cli",	       "sti",
	"cld",		     "std",		  "%g4",	       "%g5"
};

/******************************************************************************/

char *op_map_2[] = {
	/* 0 */
	"%g6",		"%g7",		"lar%Zv %Gv,%Ew",	"lsl%Zv %Gv,%Ew", 
	NULL,		NULL,		"clts",			NULL,
	"invd",		"wbinvd",	NULL,			NULL,
	NULL,		NULL,		NULL,			NULL,

	/* 1 */
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,

	/* 2 */
	"mov%Zd %Rd,%Cd", "mov%Zd %Rd,%Dd", "mov%Zd %Cd,%Rd", "mov%Zd %Dd,%Rd",
	"mov%Zd %Rd,%Td", NULL,		"mov%Zd %Td,%Rd",	NULL,
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,

	/* 3 */
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,

	/* 4 */
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,

	/* 5 */
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,

	/* 6 */
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,

	/* 7 */
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,

	/* 8 */
	"jo %Jv",	"jno %Jv",	"jb %Jv",	"jae %Jv",
	"je %Jv",	"jne %Jv",	"jbe %Jv",	"ja %Jv",
	"js %Jv",	"jns %Jv",	"jp %Jv",	"jnp %Jv",
	"jl %Jv",	"jge %Jv",	"jle %Jv",	"jg %Jv",

	/* 9 */
	"seto %Eb",	"setno %Eb",	"setb %Eb",	"setae %Eb",
	"sete %Eb",	"setne %Eb",	"setbe %Eb",	"seta %Eb",
	"sets %Eb",	"setns %Eb",	"setp %Eb",	"setnp %Eb",
	"setl %Eb",	"setge %Eb",	"setle %Eb",	"setg %Eb",

	/* A */
	"push fs",	"pop fs",	NULL,		"bt%Zv %Ev,%Gv",
	"shld%Zv %Ev,%Gv,%Ib",	"shld%Zv %Ev,%Gv,cl",
				"cmpxchg%Zb %Eb,%Gb",	"cmpxchg%Zb %Ev,%Gv",
	"push gs",	"pop gs",	NULL,		"bts%Zv %Ev,%Gv",
	"shrd%Zv %Ev,%Gv,%Ib",	"shrd%Zv %Ev,%Gv,cl",
					NULL, 		"imul%Zv %Gv,%Ev",

	/* B */
	NULL,		NULL,		"lss%Zv %Mp",	"btr%Zv %Ev,%Gv",
	"lfs%Zv %Mp",	"lgs%Zv %Mp",	"movzx%Zb %Gv,%Eb", "movzx%Zw %Gv,%Ew",
	NULL,		NULL,		"%g8%Zv %Ev,%Ib", "btc%Zv %Ev,%Gv",
	"bsf%Zv %Gv,%Ev", "bsr%Zv %Gv,%Ev", "movsx%Zb %Gv,%Eb", "movsx%Zw %Gv,%Ew",

	/* C */
	"xadd%Zb %Eb,%Gb",	"xadd%Zb %Ev,%Gv",	NULL,		NULL,
	NULL,			NULL,			NULL,		NULL,
	"bswap%Zb %Eb,%Gb",	"bswap%Zb %Ev,%Gv",	NULL,		NULL,
	NULL,			NULL,			NULL,		NULL,

	/* D */
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,

	/* E */
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,

	/* F */
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL
};

/******************************************************************************/

/*
 * Intel groups 1 to 8.
 */
char	*grp_map[9][8] = {
	/* grpStrMap[0][] is the %Ev case for grpStrMap[3][]. */
	"test%Zv %Ev,%Iv", "test%Zv %Ev,%Iv,",	"not%Zv %Ev",	"neg%Zv %Ev",
	"mul%Zv %eax,%Ev", "imul%Zv %eax,%Ev",	"div%Zv %eax,%Ev", "idiv%Zv %eax,%Ev",

	/* grp[1][] */
	"add",	"or",	"adc",	"sbb",	"and",	"sub",	"xor",	"cmp",

	/* grp[2][] */
	"rol",	"ror",	"rcl",	"rcr",	"shl",	"shr",	"shl",	"sar",

	/* grp[3][] */
	"test%Zb %Eb,%Ib", "test%Zb %Eb,%Ib,",	"not%Zb %Eb",	 "neg%Zb %Eb",
	"mul%Zb al,%Eb",   "imul%Zb al,%Eb",	"div%Zb al,%Eb", "idiv%Zb al,%Eb",

	/* grp[4][] */
	"inc%Zb %Eb",	"dec%Zb %Eb",	NULL,		NULL,
	NULL,		NULL,		NULL,		NULL,

	/* grp[5][] */
	"inc%Zv %Ev",	"dec%Zv %Ev",	"icall %Ev",	"ilcall %Ep",
	"ijmp %Ev",	"iljmp %Ep",	"push%Zv %Ev",	NULL,

	/* grp[6][] */
	"sldt %Ew",	"str %Ew",	"lldt %Ew",	"ltr %Ew",
	"verr %Ew",	"verw %Ew",	NULL,		NULL,

	/* grp[7][] */
	"sgdt %Ms",	"sidt %Ms",	"lgdt%Zv %Ms",	"lidt%Zv %Ms",
	"smsw %Ew",	NULL,		"lmsw %Ew",	"invlpg %Ms",

	/* grp[8][] */
	NULL,	NULL,	NULL,	NULL,	"bt",	"bts",	"btr",	"btc"
};

/******************************************************************************/

/*
 * NDP opcode tables.
 * Each opcode is preceded by an implicit 'f'.
 */

/* NDPtab[] is used with memory operand when mod!=3. */
char *NDP_op[8][8] = {
/*	      /0       /1       /2        /3       /4        /5       /6        /7 */
/* 0xD8 */  "adds",  "muls",  "coms",  "comps",  "subs",  "subrs",  "divs",  "divrs",
/* 0xD9 */   "lds",    NULL,   "sts",   "stps", "ldenv",   "ldcw","nstenv",  "nstcw",
/* 0xDA */ "iaddl", "imull", "icoml", "icompl", "isubl", "isubrl", "idivl", "idivrl",
/* 0xDB */  "ildl",    NULL,  "istl",  "istpl",    NULL,    "ldt",    NULL,   "stpt",
/* 0xDC */  "addl",  "mull",  "coml",  "compl",  "subl",  "subrl",  "divl",  "divrl",
/* 0xDD */   "ldl",    NULL,   "stl",   "stpl", "rstor",     NULL, "nsave",    "stsw",
/* 0xDE */ "iadds", "imuls", "icoms", "icomps", "isubs", "isubrs", "idivs", "idivrs",
/* 0xDF */  "ilds",    NULL,  "ists",  "istps",   "bld",  "ildll",  "bstp",  "istpll"
};

/*
 * NDPtab3[] is used when mod==3.
 * The opcode always takes an NDP register from the r/m field as operand.
 * The first character indicates NDP register operand format:
 *	1	op takes one fpreg operand "%st(n)"
 *	2	op takes operands "%st(0), %st(n)"
 *	3	op takes operands "%st(n), %st(0)"
 */
char *NDP_op_3[8][8] = {
/*		0xC0	0xC8	0xD0	0xD8	0xE0	0xE8	0xF0	0xF8 */
/* 0xD8 */	"2add",	"2mul",	"2com","1comp",	"2sub",	"2subr","2div", "2divr",
/* 0xD9 */ 	"1ld",	"2xch",	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
/* 0xDA */ 	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
/* 0xDB */ 	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,
/* 0xDC */ 	"3add",	"3mul",	NULL,	NULL,	"3sub",	"3subr","3div",	"3divr",
/* 0xDD */ 	"1free",NULL,	"1st",	"1stp",	"3ucom","3ucomp", NULL,	NULL,
/* 0xDE */  	"3addp","3mulp",NULL,	NULL,  "3subp","3subrp","3divp","3divrp",
/* 0xDF */ 	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL
};

/*
 * NDP_misc_op[] is used when mod==3 and the NDP_op_3[][] contains NULL.
 * This 0-terminated sorted list is searched linearly for the remaining opcodes;
 * they are too sparse for efficient table lookup.
 */
NDPMTAB	NDP_misc_op[] = {
	{ 0xD9D0,	"nop" },
	{ 0xD9E0,	"chs" },
	{ 0xD9E1,	"abs" },
	{ 0xD9E4,	"tst" },
	{ 0xD9E5,	"xam" },
	{ 0xD9E8,	"ld1" },
	{ 0xD9E9,	"ldl2t" },
	{ 0xD9EA,	"ldl2e" },
	{ 0xD9EB,	"ldpi" },
	{ 0xD9EC,	"ldlg2" },
	{ 0xD9ED,	"ldln2" },
	{ 0xD9EE,	"ldz" },
	{ 0xD9F0,	"2xm1" },
	{ 0xD9F1,	"yl2x" },
	{ 0xD9F2,	"ptan" },
	{ 0xD9F3,	"patan" },
	{ 0xD9F4,	"xtract" },
	{ 0xD9F5,	"prem1" },
	{ 0xD9F6,	"decstp" },
	{ 0xD9F7,	"incstp" },
	{ 0xD9F8,	"prem" },
	{ 0xD9F9,	"yl2xp1" },
	{ 0xD9FA,	"sqrt" },
	{ 0xD9FB,	"sincos" },
	{ 0xD9FC,	"rndint" },
	{ 0xD9FD,	"scale" },
	{ 0xD9FE,	"sin" },
	{ 0xD9FF,	"cos" },
	{ 0xDAE9,	"ucompp" },
	{ 0xDBE2,	"nclex" },
	{ 0xDBE3,	"ninit" },
	{ 0xDBE4,	"setpm" },
	{ 0xDBF4,	"rstpm" },
	{ 0xDED9,	"compp" },
	{ 0xDFE0,	"nstsw\t%ax" },
	{ 0,		NULL }
};

/******************************************************************************/

/* 
 * i80386 registers.
 */

/* Segment registers. */
char	*segReg[] = {"es", "cs", "ss", "ds", "fs", "gs" };

/* General registers. */
char	*genReg[3][8] = {
/*		    0       1       2       3       4       5       6       7 */
/* [0] 8-bit  */  "%al",  "%cl",  "%dl",  "%bl",  "%ah",  "%ch",  "%dh",  "%bh",
/* [1] 16-bit */  "%ax",  "%cx",  "%dx",  "%bx",  "%sp",  "%bp",  "%si",  "%di",
/* [2] 32-bit */ "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"
};

/* Control registers. */
char *ctrlReg[] = {
	"%cr0",	"%cr1", "%cr2", "%cr3"	
};

/* Debug registers. */
char *dbgReg[] = {
	"%dr0", "%dr1", "%dr2", "%dr3", "%dr4", "%dr5", "%dr6", "%dr7"	
};

/* Test registers. */
char *tstReg[] = {
	NULL, NULL, NULL, NULL, NULL, NULL, "%tr6", "%tr7"	
};

/* NDP registers. */
char *NDPReg[] = {
	"%st", "%st(1)", "%st(2)", "%st(3)", "%st(4)", "%st(5)", "%st(6)", "%st(7)"
};

/******************************************************************************/

/*
 * Indirect addressing mode tables.
 */

/* 16 and 32 bit indirect addressing with the mod r/m byte. */
char *modRMtab[2][8] = {

	/* [0] 16 bit indirect addressing. */
	"(%bx)(%si)",	"(%bx)(%di)",	"(%bp)(%si)",	"(%bp)(%di)",
	"(%si)",	"(%di)",	"(%bp)",	"(%bx)",

	/* [1] 32 bit indirect addressing. */
	"(%eax)",	"(%ecx)",	"(%edx)",	"(%ebx)", 
	"(%esp)",	"(%ebp)",	"(%esi)",	"(%edi)"		
};

/* 32 bit indirect indexed addressing forms with the SIB byte. */
char	*sibtab[4][8] = { 

	/* [0] scale by 1 */
	"(%eax)",	"(%ecx)",	"(%edx)",	"(%ebx)",
	NULL,		"(%ebp)",	"(%esi)",	"(%edi)",

	/* [1] scale by 2 */
	"(%eax*2)",	"(%ecx*2)",	"(%edx*2)",	"(%ebx*2)",
	 NULL,		"(%ebp*2)",	"(%esi*2)",	"(%edi*2)",

	/* [2] scale by 4 */
	"(%eax*4)",	"(%ecx*4)",	"(%edx*4)",	"(%ebx*4)", 
	 NULL,		"(%ebp*4)",	"(%esi*4)",	"(%edi*4)",

	/* [3] scale by 8 */
	"(%eax*8)",	"(%ecx*8)",	"(%edx*8)",	"(%ebx*8)", 
	 NULL,		"(%ebp*8)",	"(%esi*8)",	"(%edi*8)"
};

/******************************************************************************/

/* end of db/i386/i386db3.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.