summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-11-12 23:00:31 -0800
committerH. Peter Anvin <hpa@zytor.com>2007-11-12 23:00:31 -0800
commita5fb90834aa2e849e67bf45b478d498a6cb72062 (patch)
tree25001cb262d0a18191d68779fa6fe372b9733efb
parentbb72f7f111abe0e01081506caa11afdf37b95857 (diff)
downloadnasm-a5fb90834aa2e849e67bf45b478d498a6cb72062.tar.gz
nasm-a5fb90834aa2e849e67bf45b478d498a6cb72062.tar.bz2
nasm-a5fb90834aa2e849e67bf45b478d498a6cb72062.zip
ndisasm: factor out the common operand-extraction code
Factor out the common operand-extraction code in the disassembler, as previously done in the assembler.
-rw-r--r--disasm.c79
1 files changed, 41 insertions, 38 deletions
diff --git a/disasm.c b/disasm.c
index 3554ca8..139e8d2 100644
--- a/disasm.c
+++ b/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;