mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-03-13 17:57:12 +08:00
ndisasm: factor out the common operand-extraction code
Factor out the common operand-extraction code in the disassembler, as previously done in the assembler.
This commit is contained in:
parent
bb72f7f111
commit
a5fb90834a
79
disasm.c
79
disasm.c
@ -375,6 +375,7 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
int osize = prefix->osize;
|
||||
int asize = prefix->asize;
|
||||
int i, c;
|
||||
struct operand *opx;
|
||||
|
||||
for (i = 0; i < MAX_OPERANDS; i++) {
|
||||
ins->oprs[i].segment = ins->oprs[i].disp_size =
|
||||
@ -393,6 +394,8 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
drep = P_REP;
|
||||
|
||||
while ((c = *r++) != 0) {
|
||||
opx = &ins->oprs[c & 3];
|
||||
|
||||
switch (c) {
|
||||
case 01:
|
||||
case 02:
|
||||
@ -469,110 +472,110 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
if (d < t || d > t + 7)
|
||||
return false;
|
||||
else {
|
||||
ins->oprs[c - 010].basereg = (d-t)+
|
||||
opx->basereg = (d-t)+
|
||||
(ins->rex & REX_B ? 8 : 0);
|
||||
ins->oprs[c - 010].segment |= SEG_RMREG;
|
||||
opx->segment |= SEG_RMREG;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case4(014):
|
||||
ins->oprs[c - 014].offset = (int8_t)*data++;
|
||||
ins->oprs[c - 014].segment |= SEG_SIGNED;
|
||||
opx->offset = (int8_t)*data++;
|
||||
opx->segment |= SEG_SIGNED;
|
||||
break;
|
||||
|
||||
case4(020):
|
||||
ins->oprs[c - 020].offset = *data++;
|
||||
opx->offset = *data++;
|
||||
break;
|
||||
|
||||
case4(024):
|
||||
ins->oprs[c - 024].offset = *data++;
|
||||
opx->offset = *data++;
|
||||
break;
|
||||
|
||||
case4(030):
|
||||
ins->oprs[c - 030].offset = getu16(data);
|
||||
opx->offset = getu16(data);
|
||||
data += 2;
|
||||
break;
|
||||
|
||||
case4(034):
|
||||
if (osize == 32) {
|
||||
ins->oprs[c - 034].offset = getu32(data);
|
||||
opx->offset = getu32(data);
|
||||
data += 4;
|
||||
} else {
|
||||
ins->oprs[c - 034].offset = getu16(data);
|
||||
opx->offset = getu16(data);
|
||||
data += 2;
|
||||
}
|
||||
if (segsize != asize)
|
||||
ins->oprs[c - 034].disp_size = asize;
|
||||
opx->disp_size = asize;
|
||||
break;
|
||||
|
||||
case4(040):
|
||||
ins->oprs[c - 040].offset = getu32(data);
|
||||
opx->offset = getu32(data);
|
||||
data += 4;
|
||||
break;
|
||||
|
||||
case4(044):
|
||||
switch (asize) {
|
||||
case 16:
|
||||
ins->oprs[c - 044].offset = getu16(data);
|
||||
opx->offset = getu16(data);
|
||||
data += 2;
|
||||
if (segsize != 16)
|
||||
ins->oprs[c - 044].disp_size = 16;
|
||||
opx->disp_size = 16;
|
||||
break;
|
||||
case 32:
|
||||
ins->oprs[c - 044].offset = getu32(data);
|
||||
opx->offset = getu32(data);
|
||||
data += 4;
|
||||
if (segsize == 16)
|
||||
ins->oprs[c - 044].disp_size = 32;
|
||||
opx->disp_size = 32;
|
||||
break;
|
||||
case 64:
|
||||
ins->oprs[c - 044].offset = getu64(data);
|
||||
ins->oprs[c - 044].disp_size = 64;
|
||||
opx->offset = getu64(data);
|
||||
opx->disp_size = 64;
|
||||
data += 8;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case4(050):
|
||||
ins->oprs[c - 050].offset = gets8(data++);
|
||||
ins->oprs[c - 050].segment |= SEG_RELATIVE;
|
||||
opx->offset = gets8(data++);
|
||||
opx->segment |= SEG_RELATIVE;
|
||||
break;
|
||||
|
||||
case4(054):
|
||||
ins->oprs[c - 054].offset = getu64(data);
|
||||
opx->offset = getu64(data);
|
||||
data += 8;
|
||||
break;
|
||||
|
||||
case4(060):
|
||||
ins->oprs[c - 060].offset = gets16(data);
|
||||
opx->offset = gets16(data);
|
||||
data += 2;
|
||||
ins->oprs[c - 060].segment |= SEG_RELATIVE;
|
||||
ins->oprs[c - 060].segment &= ~SEG_32BIT;
|
||||
opx->segment |= SEG_RELATIVE;
|
||||
opx->segment &= ~SEG_32BIT;
|
||||
break;
|
||||
|
||||
case4(064):
|
||||
ins->oprs[c - 064].segment |= SEG_RELATIVE;
|
||||
opx->segment |= SEG_RELATIVE;
|
||||
if (osize == 16) {
|
||||
ins->oprs[c - 064].offset = getu16(data);
|
||||
opx->offset = getu16(data);
|
||||
data += 2;
|
||||
ins->oprs[c - 064].segment &= ~(SEG_32BIT|SEG_64BIT);
|
||||
opx->segment &= ~(SEG_32BIT|SEG_64BIT);
|
||||
} else if (osize == 32) {
|
||||
ins->oprs[c - 064].offset = getu32(data);
|
||||
opx->offset = getu32(data);
|
||||
data += 4;
|
||||
ins->oprs[c - 064].segment &= ~SEG_64BIT;
|
||||
ins->oprs[c - 064].segment |= SEG_32BIT;
|
||||
opx->segment &= ~SEG_64BIT;
|
||||
opx->segment |= SEG_32BIT;
|
||||
}
|
||||
if (segsize != osize) {
|
||||
ins->oprs[c - 064].type =
|
||||
(ins->oprs[c - 064].type & ~SIZE_MASK)
|
||||
opx->type =
|
||||
(opx->type & ~SIZE_MASK)
|
||||
| ((osize == 16) ? BITS16 : BITS32);
|
||||
}
|
||||
break;
|
||||
|
||||
case4(070):
|
||||
ins->oprs[c - 070].offset = getu32(data);
|
||||
opx->offset = getu32(data);
|
||||
data += 4;
|
||||
ins->oprs[c - 070].segment |= SEG_32BIT | SEG_RELATIVE;
|
||||
opx->segment |= SEG_32BIT | SEG_RELATIVE;
|
||||
break;
|
||||
|
||||
case4(0100):
|
||||
@ -581,23 +584,23 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
case4(0130):
|
||||
{
|
||||
int modrm = *data++;
|
||||
ins->oprs[c & 07].segment |= SEG_RMREG;
|
||||
opx->segment |= SEG_RMREG;
|
||||
data = do_ea(data, modrm, asize, segsize,
|
||||
&ins->oprs[(c >> 3) & 07], ins);
|
||||
&ins->oprs[(c >> 3) & 3], ins);
|
||||
if (!data)
|
||||
return false;
|
||||
ins->oprs[c & 07].basereg = ((modrm >> 3)&7)+
|
||||
opx->basereg = ((modrm >> 3)&7)+
|
||||
(ins->rex & REX_R ? 8 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case4(0140):
|
||||
ins->oprs[c - 0140].offset = getu16(data);
|
||||
opx->offset = getu16(data);
|
||||
data += 2;
|
||||
break;
|
||||
|
||||
case4(0150):
|
||||
ins->oprs[c - 0150].offset = getu32(data);
|
||||
opx->offset = getu32(data);
|
||||
data += 4;
|
||||
break;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user