More 64-bit ndisasm fixes.

In particular, now we should handle A0-A3 instructions.
This commit is contained in:
H. Peter Anvin 2007-04-16 02:39:56 +00:00
parent b061d595fb
commit 7cf03aff4f
2 changed files with 18 additions and 16 deletions

View File

@ -81,18 +81,24 @@ static int whichreg(int32_t regflags, int regval, int rex)
return R_AX;
if (!(REG_EAX & ~regflags))
return R_EAX;
if (!(REG_RAX & ~regflags))
return R_RAX;
if (!(REG_DL & ~regflags))
return R_DL;
if (!(REG_DX & ~regflags))
return R_DX;
if (!(REG_EDX & ~regflags))
return R_EDX;
if (!(REG_RDX & ~regflags))
return R_RDX;
if (!(REG_CL & ~regflags))
return R_CL;
if (!(REG_CX & ~regflags))
return R_CX;
if (!(REG_ECX & ~regflags))
return R_ECX;
if (!(REG_RCX & ~regflags))
return R_RCX;
if (!(FPU0 & ~regflags))
return R_ST0;
if (!(REG_CS & ~regflags))
@ -166,7 +172,7 @@ static uint8_t *do_ea(uint8_t *data, int modrm, int asize,
rm = modrm & 07;
if (mod == 3) { /* pure register version */
op->basereg = rm;
op->basereg = rm+(rex & REX_B ? 8 : 0);
op->segment |= SEG_RMREG;
return data;
}
@ -462,14 +468,15 @@ static int matches(struct itemplate *t, uint8_t *data, int asize,
ins->oprs[c - 060].segment |= SEG_RELATIVE;
ins->oprs[c - 060].segment &= ~SEG_32BIT;
} else if (c >= 064 && c <= 066) {
if (osize == 32) {
ins->oprs[c - 064].offset = getu32(data);
data += 4;
ins->oprs[c - 064].segment |= SEG_32BIT;
} else {
if (osize == 16) {
ins->oprs[c - 064].offset = getu16(data);
data += 2;
ins->oprs[c - 064].segment &= ~SEG_32BIT;
ins->oprs[c - 064].segment &= ~(SEG_32BIT|SEG_64BIT);
} else if (osize == 32) {
ins->oprs[c - 064].offset = getu32(data);
data += 4;
ins->oprs[c - 064].segment &= ~SEG_64BIT;
ins->oprs[c - 064].segment |= SEG_32BIT;
}
if (segsize != osize) {
ins->oprs[c - 064].type =
@ -499,10 +506,6 @@ static int matches(struct itemplate *t, uint8_t *data, int asize,
data = do_ea(data, modrm, asize, segsize,
&ins->oprs[(c >> 3) & 07], rex);
} else if (c >= 0300 && c <= 0302) {
if (asize)
ins->oprs[c - 0300].segment |= SEG_32BIT;
else
ins->oprs[c - 0300].segment &= ~SEG_32BIT;
a_used = TRUE;
} else if (c == 0310) {
if (asize != 16)
@ -538,7 +541,7 @@ static int matches(struct itemplate *t, uint8_t *data, int asize,
rex |= REX_W; /* 64-bit only instruction */
osize = 64;
} else if (c == 0324) {
if (!(rex & REX_P) || osize != 64)
if (!(rex & (REX_P|REX_W)) || osize != 64)
return FALSE;
} else if (c == 0330) {
int t = *r++, d = *data++;
@ -617,8 +620,7 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
else if (*data == 0x65)
segover = "gs", data++;
else if (*data == 0x66) {
if (segsize != 64) /* 66 prefix is ignored in 64-bit mode */
osize = 48 - segsize;
osize = (segsize == 16) ? 32 : 16;
data++;
} else if (*data == 0x67) {
asize = (segsize == 32) ? 16 : 32;

View File

@ -674,11 +674,11 @@ MOV reg_sreg,reg32 \1\x8E\110 386
MOV reg_al,mem_offs \301\1\xA0\45 8086,SM
MOV reg_ax,mem_offs \301\320\1\xA1\45 8086,SM
MOV reg_eax,mem_offs \301\321\1\xA1\45 386,SM
MOV reg_rax,mem_offs \301\321\1\xA1\45 X64,SM
MOV reg_rax,mem_offs \301\324\1\xA1\45 X64,SM
MOV mem_offs,reg_al \300\1\xA2\44 8086,SM
MOV mem_offs,reg_ax \300\320\1\xA3\44 8086,SM
MOV mem_offs,reg_eax \300\321\1\xA3\44 386,SM
MOV mem_offs,reg_rax \300\321\1\xA3\44 X64,SM
MOV mem_offs,reg_rax \300\324\1\xA3\44 X64,SM
MOV reg32,reg_creg \2\x0F\x20\101 386,PRIV
MOV reg64,reg_creg \323\2\x0F\x20\101 X64,PRIV
MOV reg_creg,reg32 \2\x0F\x22\110 386,PRIV