uasm.c
来自「MMURTL(tm) Computer Operating System Ver」· C语言 代码 · 共 716 行 · 第 1/2 页
C
716 行
buf[i] = getbyte();
/* sign extend the value into a U32 */
for (; i<extend; i++)
buf[i] = (buf[i-1] & 0x80) ? 0xff : 0;
if (s) /* outputs the segment value of FAR pointer */
{
xprintf("%02x%02x",buf[n-1],buf[n-2]);
n -= 2;
}
if (extend > n)
{
if (!optional)
xprintf("+");
n = 4;
}
switch (n)
{
case 1: {
xprintf("%02x",buf[0]);
break;
}
case 2: {
xprintf("%02x%02x",buf[1],buf[0]);
break;
}
case 4: {
xprintf("%02x%02x%02x%02x",buf[3],buf[2],buf[1],buf[0]);
break;
}
}
}
/*------------------------------------------------------------------------*/
void reg_name(U8 which, char size)
{
if (size == 'F')
{
xprintf( "st(%d)",which);
return;
}
if (((size == 'v') && (opsize == 32)) || (size == 'd'))
{
xprintf("E");
}
if (size == 'b')
{
xprintf( "%s", breg_names[which]);
}
else
{
xprintf( "%s", wreg_names[which]);
}
}
/******************************************************************
This takes in two chars that represent part of the op code and
puts out the proper text to match what the letter represents.
c is the first char after the tilde and t is next one. See
opcode1[] strings for what the chars mean.
*******************************************************************/
void escape(char c, char t)
{
S32 delta, vals;
U8 b2;
S8 valsb;
S16 valsw;
switch (c)
{
case 'A': /* Direct Address */
ohex(t, 4, 0, 32);
break;
case 'C': /* Reg of R/M picks control reg */
xprintf("CR%d",reg(modrm()));
break;
case 'D': /* Reg of R/M pick debug reg */
xprintf("DR%d",modrm());
break;
case 'E': /* R/M picks operand */
do_modrm(t);
break;
case 'G': /* Reg of R/M picks general reg */
if (t == 'F')
reg_name((modrm()&7), t);
else
reg_name(reg(modrm()), t);
break;
case 'I': /* Immediate data */
ohex(t, 0, 0, opsize);
break;
case 'J': /* Relative IP offset */
switch (bytes(t))
{
case 1:
valsb = getbyte(); /* must remian signed! */
vals = valsb;
break;
case 2:
valsb = getbyte(); /*RAB Made SIGNEd bytes/Words */
valsw = getbyte()<<8;
vals = valsw + valsb;
break;
case 4:
vals = getbyte();
vals |= getbyte() << 8;
vals |= getbyte() << 16;
vals |= getbyte() << 24;
break;
}
delta = addrIn + vals;
xprintf( "%x",delta);
break;
case 'M': /* R/M picks memory */
do_modrm(t);
break;
case 'O': /* NO R/M, Offset only */
decode("~p:[");
ohex(t, 4, 0, 32);
xprintf("]");
break;
case 'R': /* Mod of R/M pick REG only */
do_modrm(t);
break;
case 'S': /* Reg of R/M picks seg reg */
xprintf( "%s", seg_names[reg(modrm())]);
break;
case 'T': /* Reg of R/M picks test reg */
xprintf( "TR%d",modrm());
break;
case 'X': /* DS:ESI */
xprintf("DS:[ESI]");
break;
case 'Y': /* ES:EDI */
xprintf("ES:[EDI]");
break;
case '2': /* Prefix of 2 byte opcode */
b2 = getbyte();
if (b2 < 0x10)
decode(SecOp00[b2]);
else if ((b2 > 0x1F) && (b2 < 0x30))
decode(SecOp20[b2-0x20]);
else if ((b2 > 0x7F) && (b2 < 0xC0))
decode(SecOp80[b2-0x80]);
else
xprintf("<bogus>");
break;
case 'e': /* t is part of reg name */
if (opsize == 32)
{
if (t == 'w') /* put out "d" if t is "w" on 32 bit opsize */
xprintf("D");
else
{
xprintf("E"); /* put out "E" if not t <> "w" then put t */
xprintf("%c",t);
}
}
else {
xprintf("%c",t);
}
break;
case 'f': /* floating point */
xprintf("<Float Op>");
/* floating_point(t-'0'); */
break;
case 'g': /* do R/M group 'n' */
decode(groups[t-'0'][reg(modrm())]);
break;
case 'p': /* Segment prefix */
switch (t)
{
case 'C': /* CS */
case 'D': /* DS */
case 'E': /* ES */
case 'F': /* FS */
case 'G': /* GS */
case 'S': /* SS */
prefix = t;
decode(opmap1[getbyte()]);
break;
case ':':
if (prefix) {
xprintf("%cS:",prefix);
}
break;
case ' ':
decode(opmap1[getbyte()]);
break;
}
break;
case 's': /* Size override */
if (t=='o') { /* o is operand */
opsize = 48 - opsize;
decode(opmap1[getbyte()]);
}
break;
}
}
/******************************************
This expands and outputs the instruction
string passed in if it finds the escape
character (tilde).
******************************************/
void decode(char *s)
{
char c;
if (s == 0) /* if NULL pointer, then it's BAD */
{
xprintf("<invalid>");
}
while ((c = *s++) != 0) /* put next char in c */
{
if (c == '~') /* if c is ~ then ESCAPE */
{
c = *s++; /* get letter representing value */
escape(c, *s++);
}
else
if (c == ' ') /* space */
xprintf(" ");
else {
xprintf("%c",c); /* else put out the char found! */
}
}
}
/* outputs 'scale-index-base' instructions */
void do_sib(int m)
{
int s, i, b;
s = ((sib()) >> 6) & 7; /* SSxxxxxx Scale */
i = ((sib()) >> 3) & 7; /* xxIIIxxx Index */
b = sib() & 7; /* xxxxxBBB Base */
switch (b)
{
case 0: decode("~p:[EAX"); break;
case 1: decode("~p:[ECX"); break;
case 2: decode("~p:[EDX"); break;
case 3: decode("~p:[EBX"); break;
case 4: decode("~p:[ESP"); break;
case 5:
if (m == 0)
{
decode("~p:[");
ohex('d', 4, 0, 32);
}
else
decode("~p:[EBP");
break;
case 6: decode("~p:[ESI"); break;
case 7: decode("~p:[EDI"); break;
}
switch (i)
{
case 0: xprintf("+EAX"); break;
case 1: xprintf("+ECX"); break;
case 2: xprintf("+EDX"); break;
case 3: xprintf("+EBX"); break;
case 4: break;
case 5: xprintf("+EBP"); break;
case 6: xprintf("+ESI"); break;
case 7: xprintf("+EDI"); break;
}
if (i != 4)
switch (s)
{
case 0: break;
case 1: xprintf("*2"); break;
case 2: xprintf("*4"); break;
case 3: xprintf("*8"); break;
}
}
/*------------------------------------------------------------------------*/
void do_modrm(char t)
{
int m;
int r;
m = ((modrm()) >> 6) & 7;
r = modrm() & 7;
if (m == 3)
{
reg_name(r, t);
return;
}
if ((m == 0) && (r == 5))
{
decode("~p:[");
ohex('d', 4, 0, 32);
xprintf("]");
return;
}
if (r != 4)
decode("~p:[");
switch (r)
{
case 0: xprintf("EAX"); break;
case 1: xprintf("ECX"); break;
case 2: xprintf("EDX"); break;
case 3: xprintf("EBX"); break;
case 4: do_sib(m); break;
case 5: xprintf("EBP"); break;
case 6: xprintf("ESI"); break;
case 7: xprintf("EDI"); break;
}
switch (m)
{
case 1:
ohex('b', 4, 0, 32);
break;
case 2:
xprintf("+");
ohex('v', 4, 0, 32);
break;
}
xprintf("]");
}
/***********************************************
This disassembles one instruction each time it
is called.
************************************************/
U32 disassemble(U32 Addr)
{
prefix = 0;
fmodrmv = 0;
fsibv = 0;
opsize = SEGSIZE; /* default operand size is DWORD */
addrIn = Addr;
xprintf( "%08x ", addrIn);
decode(opmap1[getbyte()]); /* decode instruction and output */
xprintf( "\r\n");
return addrIn;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?