mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-02-17 17:19:35 +08:00
Un-special-case "xchg rax,rax"; disassemble o64
Un-special-case "xchg rax,rax"; allow it to be encoded as 48 90 for orthogonality's sake. It's a no-op, to be sure, but so are many other instructions. "xchg eax,eax" is still special-cased in 64-bit mode since it is not a no-op; unadorned opcode 90 is now simply "nop" and nothing else. Make the disassembler detect unused REX.W and display them as an "o64" prefix.
This commit is contained in:
parent
fb0c90cdbe
commit
bb72f7f111
35
disasm.c
35
disasm.c
@ -382,6 +382,7 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
}
|
||||
ins->condition = -1;
|
||||
ins->rex = prefix->rex;
|
||||
memset(ins->prefixes, 0, sizeof ins->prefixes);
|
||||
|
||||
if (t->flags & (segsize == 64 ? IF_NOLONG : IF_LONG))
|
||||
return false;
|
||||
@ -712,11 +713,13 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
case 0323:
|
||||
ins->rex |= REX_W; /* 64-bit only instruction */
|
||||
osize = 64;
|
||||
o_used = true;
|
||||
break;
|
||||
|
||||
case 0324:
|
||||
if (!(ins->rex & (REX_P|REX_W)) || osize != 64)
|
||||
return false;
|
||||
o_used = true;
|
||||
break;
|
||||
|
||||
case 0330:
|
||||
@ -779,7 +782,7 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
case 0367:
|
||||
if (!prefix->asp)
|
||||
return false;
|
||||
o_used = true;
|
||||
a_used = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -809,10 +812,26 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
return false;
|
||||
ins->prefixes[PPS_LREP] = drep;
|
||||
}
|
||||
if (!o_used && osize == ((segsize == 16) ? 32 : 16)) {
|
||||
if (ins->prefixes[PPS_OSIZE])
|
||||
return false;
|
||||
ins->prefixes[PPS_OSIZE] = osize == 16 ? P_O16 : P_O32;
|
||||
if (!o_used) {
|
||||
if (osize != ((segsize == 16) ? 16 : 32)) {
|
||||
enum prefixes pfx = 0;
|
||||
|
||||
switch (osize) {
|
||||
case 16:
|
||||
pfx = P_O16;
|
||||
break;
|
||||
case 32:
|
||||
pfx = P_O32;
|
||||
break;
|
||||
case 64:
|
||||
pfx = P_O64;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ins->prefixes[PPS_OSIZE])
|
||||
return false;
|
||||
ins->prefixes[PPS_OSIZE] = pfx;
|
||||
}
|
||||
}
|
||||
if (!a_used && asize != segsize) {
|
||||
if (ins->prefixes[PPS_ASIZE])
|
||||
@ -1006,12 +1025,18 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
|
||||
case P_A32:
|
||||
slen += snprintf(output + slen, outbufsize - slen, "a32 ");
|
||||
break;
|
||||
case P_A64:
|
||||
slen += snprintf(output + slen, outbufsize - slen, "a64 ");
|
||||
break;
|
||||
case P_O16:
|
||||
slen += snprintf(output + slen, outbufsize - slen, "o16 ");
|
||||
break;
|
||||
case P_O32:
|
||||
slen += snprintf(output + slen, outbufsize - slen, "o32 ");
|
||||
break;
|
||||
case P_O64:
|
||||
slen += snprintf(output + slen, outbufsize - slen, "o64 ");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -848,7 +848,7 @@ PADDUSW mmxreg,mmxrm \2\x0F\xDD\110 PENT,MMX,SM
|
||||
PADDW mmxreg,mmxrm \2\x0F\xFD\110 PENT,MMX,SM
|
||||
PAND mmxreg,mmxrm \2\x0F\xDB\110 PENT,MMX,SM
|
||||
PANDN mmxreg,mmxrm \2\x0F\xDF\110 PENT,MMX,SM
|
||||
PAUSE void \333\1\x90 8086
|
||||
PAUSE void \314\333\1\x90 8086
|
||||
PAVEB mmxreg,mmxrm \2\x0F\x50\110 PENT,MMX,SM,CYRIX
|
||||
PAVGUSB mmxreg,mmxrm \2\x0F\x0F\110\01\xBF PENT,3DNOW,SM
|
||||
PCMPEQB mmxreg,mmxrm \2\x0F\x74\110 PENT,MMX,SM
|
||||
@ -1271,12 +1271,13 @@ XBTS reg32,mem \321\2\x0F\xA6\110 386,SD,UNDOC,ND
|
||||
XBTS reg32,reg32 \321\2\x0F\xA6\110 386,UNDOC,ND
|
||||
XCHG reg_ax,reg16 \320\11\x90 8086
|
||||
XCHG reg_eax,reg32na \321\11\x90 386
|
||||
XCHG reg_rax,reg64na \324\11\x90 X64
|
||||
XCHG reg_rax,reg64 \324\11\x90 X64
|
||||
XCHG reg16,reg_ax \320\10\x90 8086
|
||||
XCHG reg32na,reg_eax \321\10\x90 386
|
||||
XCHG reg64na,reg_rax \324\10\x90 X64
|
||||
XCHG reg64,reg_rax \324\10\x90 X64
|
||||
; This must be NOLONG since opcode 90 is NOP, and in 64-bit mode
|
||||
; "xchg eax,eax" is *not* a NOP.
|
||||
XCHG reg_eax,reg_eax \321\1\x90 386,NOLONG
|
||||
XCHG reg_rax,reg_rax \323\1\x90 X64
|
||||
XCHG reg8,mem \1\x86\110 8086,SM
|
||||
XCHG reg8,reg8 \1\x86\110 8086
|
||||
XCHG reg16,mem \320\1\x87\110 8086,SM
|
||||
|
14
test/nop.asm
Normal file
14
test/nop.asm
Normal file
@ -0,0 +1,14 @@
|
||||
bits 64
|
||||
|
||||
nop
|
||||
o64 nop
|
||||
pause
|
||||
o64 pause
|
||||
|
||||
xchg ax,ax
|
||||
xchg eax,eax
|
||||
xchg rax,rax
|
||||
|
||||
rep xchg ax,ax
|
||||
rep xchg eax,eax
|
||||
rep xchg rax,rax
|
Loading…
Reference in New Issue
Block a user