mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-03-19 18:00:23 +08:00
Initial support for four arguments per instruction
For SSE5, we will need to support four arguments per instruction.
This commit is contained in:
parent
3a7edd73a3
commit
7eb4a38793
275
assemble.c
275
assemble.c
@ -12,39 +12,36 @@
|
||||
* (POP is never used for CS) depending on operand 0
|
||||
* \5, \7 - the second byte of POP/PUSH codes for FS, GS, depending
|
||||
* on operand 0
|
||||
* \10, \11, \12 - a literal byte follows in the code stream, to be added
|
||||
* to the register value of operand 0, 1 or 2
|
||||
* \17 - encodes the literal byte 0. (Some compilers don't take
|
||||
* kindly to a zero byte in the _middle_ of a compile time
|
||||
* string constant, so I had to put this hack in.)
|
||||
* \14, \15, \16 - a signed byte immediate operand, from operand 0, 1 or 2
|
||||
* \20, \21, \22 - a byte immediate operand, from operand 0, 1 or 2
|
||||
* \24, \25, \26 - an unsigned byte immediate operand, from operand 0, 1 or 2
|
||||
* \30, \31, \32 - a word immediate operand, from operand 0, 1 or 2
|
||||
* \34, \35, \36 - select between \3[012] and \4[012] depending on 16/32 bit
|
||||
* \10..\13 - a literal byte follows in the code stream, to be added
|
||||
* to the register value of operand 0..3
|
||||
* \14..\17 - a signed byte immediate operand, from operand 0..3
|
||||
* \20..\23 - a byte immediate operand, from operand 0..3
|
||||
* \24..\27 - an unsigned byte immediate operand, from operand 0..3
|
||||
* \30..\33 - a word immediate operand, from operand 0..3
|
||||
* \34..\37 - select between \3[0-3] and \4[0-3] depending on 16/32 bit
|
||||
* assembly mode or the operand-size override on the operand
|
||||
* \37 - a word constant, from the _segment_ part of operand 0
|
||||
* \40, \41, \42 - a long immediate operand, from operand 0, 1 or 2
|
||||
* \44, \45, \46 - select between \3[012], \4[012] and \5[456]
|
||||
* \40..\43 - a long immediate operand, from operand 0..3
|
||||
* \44..\47 - select between \3[0-3], \4[0-3] and \5[4-7]
|
||||
* depending on assembly mode or the address-size override
|
||||
* on the operand.
|
||||
* \50, \51, \52 - a byte relative operand, from operand 0, 1 or 2
|
||||
* \54, \55, \56 - a qword immediate operand, from operand 0, 1 or 2
|
||||
* \60, \61, \62 - a word relative operand, from operand 0, 1 or 2
|
||||
* \64, \65, \66 - select between \6[012] and \7[012] depending on 16/32 bit
|
||||
* \50..\53 - a byte relative operand, from operand 0..3
|
||||
* \54..\57 - a qword immediate operand, from operand 0..3
|
||||
* \60..\63 - a word relative operand, from operand 0..3
|
||||
* \64..\67 - select between \6[0-3] and \7[0-3] depending on 16/32 bit
|
||||
* assembly mode or the operand-size override on the operand
|
||||
* \70, \71, \72 - a long relative operand, from operand 0, 1 or 2
|
||||
* \70..\73 - a long relative operand, from operand 0..3
|
||||
* \74..\77 - a word constant, from the _segment_ part of operand 0..3
|
||||
* \1ab - a ModRM, calculated on EA in operand a, with the spare
|
||||
* field the register value of operand b.
|
||||
* \130,\131,\132 - an immediate word or signed byte for operand 0, 1, or 2
|
||||
* \133,\134,\135 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
|
||||
* \140..\143 - an immediate word or signed byte for operand 0..3
|
||||
* \144..\147 - or 2 (s-field) into next opcode byte if operand 0..3
|
||||
* is a signed byte rather than a word.
|
||||
* \140,\141,\142 - an immediate dword or signed byte for operand 0, 1, or 2
|
||||
* \143,\144,\145 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
|
||||
* \150..\153 - an immediate dword or signed byte for operand 0..3
|
||||
* \154..\157 - or 2 (s-field) into next opcode byte if operand 0..3
|
||||
* is a signed byte rather than a dword.
|
||||
* \150,\151,\152 - an immediate qword or signed byte for operand 0, 1, or 2
|
||||
* \153,\154,\155 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
|
||||
* is a signed byte rather than a qword.
|
||||
* \170 - encodes the literal byte 0. (Some compilers don't take
|
||||
* kindly to a zero byte in the _middle_ of a compile time
|
||||
* string constant, so I had to put this hack in.)
|
||||
* \2ab - a ModRM, calculated on EA in operand a, with the spare
|
||||
* field equal to digit b.
|
||||
* \30x - might be an 0x67 byte, depending on the address size of
|
||||
@ -730,73 +727,79 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
|
||||
case 010:
|
||||
case 011:
|
||||
case 012:
|
||||
case 013:
|
||||
ins->rex |=
|
||||
op_rexflags(&ins->oprs[c - 010], REX_B|REX_H|REX_P|REX_W);
|
||||
codes++, length++;
|
||||
break;
|
||||
case 017:
|
||||
length++;
|
||||
break;
|
||||
case 014:
|
||||
case 015:
|
||||
case 016:
|
||||
case 017:
|
||||
length++;
|
||||
break;
|
||||
case 020:
|
||||
case 021:
|
||||
case 022:
|
||||
case 023:
|
||||
length++;
|
||||
break;
|
||||
case 024:
|
||||
case 025:
|
||||
case 026:
|
||||
case 027:
|
||||
length++;
|
||||
break;
|
||||
case 030:
|
||||
case 031:
|
||||
case 032:
|
||||
case 033:
|
||||
length += 2;
|
||||
break;
|
||||
case 034:
|
||||
case 035:
|
||||
case 036:
|
||||
case 037:
|
||||
if (ins->oprs[c - 034].type & (BITS16 | BITS32 | BITS64))
|
||||
length += (ins->oprs[c - 034].type & BITS16) ? 2 : 4;
|
||||
else
|
||||
length += (bits == 16) ? 2 : 4;
|
||||
break;
|
||||
case 037:
|
||||
length += 2;
|
||||
break;
|
||||
case 040:
|
||||
case 041:
|
||||
case 042:
|
||||
case 043:
|
||||
length += 4;
|
||||
break;
|
||||
case 044:
|
||||
case 045:
|
||||
case 046:
|
||||
case 047:
|
||||
length += ((ins->oprs[c - 044].addr_size ?
|
||||
ins->oprs[c - 044].addr_size : bits) >> 3);
|
||||
break;
|
||||
case 050:
|
||||
case 051:
|
||||
case 052:
|
||||
case 053:
|
||||
length++;
|
||||
break;
|
||||
case 054:
|
||||
case 055:
|
||||
case 056:
|
||||
case 057:
|
||||
length += 8; /* MOV reg64/imm */
|
||||
break;
|
||||
case 060:
|
||||
case 061:
|
||||
case 062:
|
||||
case 063:
|
||||
length += 2;
|
||||
break;
|
||||
case 064:
|
||||
case 065:
|
||||
case 066:
|
||||
case 067:
|
||||
if (ins->oprs[c - 064].type & (BITS16 | BITS32 | BITS64))
|
||||
length += (ins->oprs[c - 064].type & BITS16) ? 2 : 4;
|
||||
else
|
||||
@ -805,33 +808,48 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
|
||||
case 070:
|
||||
case 071:
|
||||
case 072:
|
||||
case 073:
|
||||
length += 4;
|
||||
break;
|
||||
case 0130:
|
||||
case 0131:
|
||||
case 0132:
|
||||
length += is_sbyte(ins, c - 0130, 16) ? 1 : 2;
|
||||
break;
|
||||
case 0133:
|
||||
case 0134:
|
||||
case 0135:
|
||||
codes += 2;
|
||||
length++;
|
||||
case 074:
|
||||
case 075:
|
||||
case 076:
|
||||
case 077:
|
||||
length += 2;
|
||||
break;
|
||||
case 0140:
|
||||
case 0141:
|
||||
case 0142:
|
||||
length += is_sbyte(ins, c - 0140, 32) ? 1 : 4;
|
||||
case 0143:
|
||||
length += is_sbyte(ins, c - 0140, 16) ? 1 : 2;
|
||||
break;
|
||||
case 0143:
|
||||
case 0144:
|
||||
case 0145:
|
||||
case 0146:
|
||||
case 0147:
|
||||
codes += 2;
|
||||
length++;
|
||||
break;
|
||||
case 0150:
|
||||
case 0151:
|
||||
case 0152:
|
||||
case 0153:
|
||||
length += is_sbyte(ins, c - 0150, 32) ? 1 : 4;
|
||||
break;
|
||||
case 0154:
|
||||
case 0155:
|
||||
case 0156:
|
||||
case 0157:
|
||||
codes += 2;
|
||||
length++;
|
||||
break;
|
||||
case 0170:
|
||||
length++;
|
||||
break;
|
||||
case 0300:
|
||||
case 0301:
|
||||
case 0302:
|
||||
case 0303:
|
||||
length += chsize(&ins->oprs[c - 0300], bits);
|
||||
break;
|
||||
case 0310:
|
||||
@ -1020,21 +1038,17 @@ static void gencode(int32_t segment, int32_t offset, int bits,
|
||||
case 010:
|
||||
case 011:
|
||||
case 012:
|
||||
case 013:
|
||||
EMIT_REX();
|
||||
bytes[0] = *codes++ + ((regval(&ins->oprs[c - 010])) & 7);
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
break;
|
||||
|
||||
case 017:
|
||||
bytes[0] = 0;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
break;
|
||||
|
||||
case 014:
|
||||
case 015:
|
||||
case 016:
|
||||
case 017:
|
||||
if (ins->oprs[c - 014].offset < -128
|
||||
|| ins->oprs[c - 014].offset > 127) {
|
||||
errfunc(ERR_WARNING, "signed byte value exceeds bounds");
|
||||
@ -1055,6 +1069,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
|
||||
case 020:
|
||||
case 021:
|
||||
case 022:
|
||||
case 023:
|
||||
if (ins->oprs[c - 020].offset < -256
|
||||
|| ins->oprs[c - 020].offset > 255) {
|
||||
errfunc(ERR_WARNING, "byte value exceeds bounds");
|
||||
@ -1074,6 +1089,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
|
||||
case 024:
|
||||
case 025:
|
||||
case 026:
|
||||
case 027:
|
||||
if (ins->oprs[c - 024].offset < 0
|
||||
|| ins->oprs[c - 024].offset > 255)
|
||||
errfunc(ERR_WARNING, "unsigned byte value exceeds bounds");
|
||||
@ -1092,6 +1108,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
|
||||
case 030:
|
||||
case 031:
|
||||
case 032:
|
||||
case 033:
|
||||
if (ins->oprs[c - 030].segment == NO_SEG &&
|
||||
ins->oprs[c - 030].wrt == NO_SEG &&
|
||||
(ins->oprs[c - 030].offset < -65536L ||
|
||||
@ -1107,6 +1124,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
|
||||
case 034:
|
||||
case 035:
|
||||
case 036:
|
||||
case 037:
|
||||
if (ins->oprs[c - 034].type & (BITS16 | BITS32))
|
||||
size = (ins->oprs[c - 034].type & BITS16) ? 2 : 4;
|
||||
else
|
||||
@ -1119,20 +1137,10 @@ static void gencode(int32_t segment, int32_t offset, int bits,
|
||||
offset += size;
|
||||
break;
|
||||
|
||||
case 037:
|
||||
if (ins->oprs[0].segment == NO_SEG)
|
||||
errfunc(ERR_NONFATAL, "value referenced by FAR is not"
|
||||
" relocatable");
|
||||
data = 0L;
|
||||
out(offset, segment, &data, OUT_ADDRESS + 2,
|
||||
outfmt->segbase(1 + ins->oprs[0].segment),
|
||||
ins->oprs[0].wrt);
|
||||
offset += 2;
|
||||
break;
|
||||
|
||||
case 040:
|
||||
case 041:
|
||||
case 042:
|
||||
case 043:
|
||||
data = ins->oprs[c - 040].offset;
|
||||
out(offset, segment, &data, OUT_ADDRESS + 4,
|
||||
ins->oprs[c - 040].segment, ins->oprs[c - 040].wrt);
|
||||
@ -1142,6 +1150,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
|
||||
case 044:
|
||||
case 045:
|
||||
case 046:
|
||||
case 047:
|
||||
data = ins->oprs[c - 044].offset;
|
||||
size = ((ins->oprs[c - 044].addr_size ?
|
||||
ins->oprs[c - 044].addr_size : bits) >> 3);
|
||||
@ -1155,6 +1164,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
|
||||
case 050:
|
||||
case 051:
|
||||
case 052:
|
||||
case 053:
|
||||
if (ins->oprs[c - 050].segment != segment)
|
||||
errfunc(ERR_NONFATAL,
|
||||
"short relative jump outside segment");
|
||||
@ -1169,6 +1179,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
|
||||
case 054:
|
||||
case 055:
|
||||
case 056:
|
||||
case 057:
|
||||
data = (int64_t)ins->oprs[c - 054].offset;
|
||||
out(offset, segment, &data, OUT_ADDRESS + 8,
|
||||
ins->oprs[c - 054].segment, ins->oprs[c - 054].wrt);
|
||||
@ -1178,6 +1189,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
|
||||
case 060:
|
||||
case 061:
|
||||
case 062:
|
||||
case 063:
|
||||
if (ins->oprs[c - 060].segment != segment) {
|
||||
data = ins->oprs[c - 060].offset;
|
||||
out(offset, segment, &data,
|
||||
@ -1194,6 +1206,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
|
||||
case 064:
|
||||
case 065:
|
||||
case 066:
|
||||
case 067:
|
||||
if (ins->oprs[c - 064].type & (BITS16 | BITS32 | BITS64))
|
||||
size = (ins->oprs[c - 064].type & BITS16) ? 2 : 4;
|
||||
else
|
||||
@ -1214,6 +1227,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
|
||||
case 070:
|
||||
case 071:
|
||||
case 072:
|
||||
case 073:
|
||||
if (ins->oprs[c - 070].segment != segment) {
|
||||
data = ins->oprs[c - 070].offset;
|
||||
out(offset, segment, &data,
|
||||
@ -1227,70 +1241,95 @@ static void gencode(int32_t segment, int32_t offset, int bits,
|
||||
offset += 4;
|
||||
break;
|
||||
|
||||
case 0130:
|
||||
case 0131:
|
||||
case 0132:
|
||||
data = ins->oprs[c - 0130].offset;
|
||||
if (is_sbyte(ins, c - 0130, 16)) {
|
||||
bytes[0] = data;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
|
||||
NO_SEG);
|
||||
offset++;
|
||||
} else {
|
||||
if (ins->oprs[c - 0130].segment == NO_SEG &&
|
||||
ins->oprs[c - 0130].wrt == NO_SEG &&
|
||||
(data < -65536L || data > 65535L)) {
|
||||
errfunc(ERR_WARNING, "word value exceeds bounds");
|
||||
}
|
||||
out(offset, segment, &data, OUT_ADDRESS + 2,
|
||||
ins->oprs[c - 0130].segment, ins->oprs[c - 0130].wrt);
|
||||
offset += 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0133:
|
||||
case 0134:
|
||||
case 0135:
|
||||
EMIT_REX();
|
||||
codes++;
|
||||
bytes[0] = *codes++;
|
||||
if (is_sbyte(ins, c - 0133, 16))
|
||||
bytes[0] |= 2; /* s-bit */
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
offset++;
|
||||
case 074:
|
||||
case 075:
|
||||
case 076:
|
||||
case 077:
|
||||
if (ins->oprs[c - 074].segment == NO_SEG)
|
||||
errfunc(ERR_NONFATAL, "value referenced by FAR is not"
|
||||
" relocatable");
|
||||
data = 0L;
|
||||
out(offset, segment, &data, OUT_ADDRESS + 2,
|
||||
outfmt->segbase(1 + ins->oprs[c - 074].segment),
|
||||
ins->oprs[c - 074].wrt);
|
||||
offset += 2;
|
||||
break;
|
||||
|
||||
case 0140:
|
||||
case 0141:
|
||||
case 0142:
|
||||
case 0143:
|
||||
data = ins->oprs[c - 0140].offset;
|
||||
if (is_sbyte(ins, c - 0140, 32)) {
|
||||
if (is_sbyte(ins, c - 0140, 16)) {
|
||||
bytes[0] = data;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
|
||||
NO_SEG);
|
||||
offset++;
|
||||
} else {
|
||||
if (ins->oprs[c - 0140].segment == NO_SEG &&
|
||||
ins->oprs[c - 0140].wrt == NO_SEG &&
|
||||
(data < -65536L || data > 65535L)) {
|
||||
errfunc(ERR_WARNING, "word value exceeds bounds");
|
||||
}
|
||||
out(offset, segment, &data, OUT_ADDRESS + 2,
|
||||
ins->oprs[c - 0140].segment, ins->oprs[c - 0130].wrt);
|
||||
offset += 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0144:
|
||||
case 0145:
|
||||
case 0146:
|
||||
case 0147:
|
||||
EMIT_REX();
|
||||
codes++;
|
||||
bytes[0] = *codes++;
|
||||
if (is_sbyte(ins, c - 0144, 16))
|
||||
bytes[0] |= 2; /* s-bit */
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
offset++;
|
||||
break;
|
||||
|
||||
case 0150:
|
||||
case 0151:
|
||||
case 0152:
|
||||
case 0153:
|
||||
data = ins->oprs[c - 0150].offset;
|
||||
if (is_sbyte(ins, c - 0150, 32)) {
|
||||
bytes[0] = data;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
|
||||
NO_SEG);
|
||||
offset++;
|
||||
} else {
|
||||
out(offset, segment, &data, OUT_ADDRESS + 4,
|
||||
ins->oprs[c - 0140].segment, ins->oprs[c - 0140].wrt);
|
||||
ins->oprs[c - 0150].segment, ins->oprs[c - 0140].wrt);
|
||||
offset += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0143:
|
||||
case 0144:
|
||||
case 0145:
|
||||
case 0154:
|
||||
case 0155:
|
||||
case 0156:
|
||||
case 0157:
|
||||
EMIT_REX();
|
||||
codes++;
|
||||
bytes[0] = *codes++;
|
||||
if (is_sbyte(ins, c - 0143, 32))
|
||||
if (is_sbyte(ins, c - 0154, 32))
|
||||
bytes[0] |= 2; /* s-bit */
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
offset++;
|
||||
break;
|
||||
|
||||
case 0170:
|
||||
bytes[0] = 0;
|
||||
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
|
||||
offset += 1;
|
||||
break;
|
||||
|
||||
case 0300:
|
||||
case 0301:
|
||||
case 0302:
|
||||
case 0303:
|
||||
if (chsize(&ins->oprs[c - 0300], bits)) {
|
||||
*bytes = 0x67;
|
||||
out(offset, segment, bytes,
|
||||
@ -1537,7 +1576,7 @@ static int rexflags(int val, int32_t flags, int mask)
|
||||
|
||||
static int matches(const struct itemplate *itemp, insn * instruction, int bits)
|
||||
{
|
||||
int i, size[3], asize, oprs, ret;
|
||||
int i, size[MAX_OPERANDS], asize, oprs, ret;
|
||||
|
||||
ret = 100;
|
||||
|
||||
@ -1579,7 +1618,7 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
|
||||
* Check operand sizes
|
||||
*/
|
||||
if (itemp->flags & IF_ARMASK) {
|
||||
size[0] = size[1] = size[2] = 0;
|
||||
memset(size, 0, sizeof size);
|
||||
|
||||
switch (itemp->flags & IF_ARMASK) {
|
||||
case IF_AR0:
|
||||
@ -1591,34 +1630,54 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
|
||||
case IF_AR2:
|
||||
i = 2;
|
||||
break;
|
||||
#if 0 /* Need to reorganize instruction flags to fit IF_AR3 */
|
||||
case IF_AR3:
|
||||
i = 3;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break; /* Shouldn't happen */
|
||||
}
|
||||
if (itemp->flags & IF_SB) {
|
||||
switch (itemp->flags & IF_SMASK) {
|
||||
case IF_SB:
|
||||
size[i] = BITS8;
|
||||
} else if (itemp->flags & IF_SW) {
|
||||
break;
|
||||
case IF_SW:
|
||||
size[i] = BITS16;
|
||||
} else if (itemp->flags & IF_SD) {
|
||||
break;
|
||||
case IF_SD:
|
||||
size[i] = BITS32;
|
||||
} else if (itemp->flags & IF_SQ) {
|
||||
break;
|
||||
case IF_SQ:
|
||||
size[i] = BITS64;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
asize = 0;
|
||||
if (itemp->flags & IF_SB) {
|
||||
switch (itemp->flags & IF_SMASK) {
|
||||
case IF_SB:
|
||||
asize = BITS8;
|
||||
oprs = itemp->operands;
|
||||
} else if (itemp->flags & IF_SW) {
|
||||
break;
|
||||
case IF_SW:
|
||||
asize = BITS16;
|
||||
oprs = itemp->operands;
|
||||
} else if (itemp->flags & IF_SD) {
|
||||
break;
|
||||
case IF_SD:
|
||||
asize = BITS32;
|
||||
oprs = itemp->operands;
|
||||
} else if (itemp->flags & IF_SQ) {
|
||||
break;
|
||||
case IF_SQ:
|
||||
asize = BITS64;
|
||||
oprs = itemp->operands;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
size[0] = size[1] = size[2] = asize;
|
||||
for (i = 0; i < MAX_OPERANDS; i++)
|
||||
size[i] = asize;
|
||||
}
|
||||
|
||||
if (itemp->flags & (IF_SM | IF_SM2)) {
|
||||
|
54
disasm.c
54
disasm.c
@ -341,12 +341,12 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
uint8_t lock = prefix->lock;
|
||||
int osize = prefix->osize;
|
||||
int asize = prefix->asize;
|
||||
int i;
|
||||
|
||||
ins->oprs[0].segment = ins->oprs[1].segment =
|
||||
ins->oprs[2].segment =
|
||||
ins->oprs[0].addr_size = ins->oprs[1].addr_size =
|
||||
ins->oprs[2].addr_size = (segsize == 64 ? SEG_64BIT :
|
||||
segsize == 32 ? SEG_32BIT : 0);
|
||||
for (i = 0; i < MAX_OPERANDS; i++) {
|
||||
ins->oprs[i].segment = ins->oprs[i].addr_size =
|
||||
(segsize == 64 ? SEG_64BIT : segsize == 32 ? SEG_32BIT : 0);
|
||||
}
|
||||
ins->condition = -1;
|
||||
ins->rex = prefix->rex;
|
||||
|
||||
@ -419,7 +419,7 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
} else if (c >= 010 && c <= 012) {
|
||||
} else if (c >= 010 && c <= 013) {
|
||||
int t = *r++, d = *data++;
|
||||
if (d < t || d > t + 7)
|
||||
return FALSE;
|
||||
@ -428,20 +428,17 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
(ins->rex & REX_B ? 8 : 0);
|
||||
ins->oprs[c - 010].segment |= SEG_RMREG;
|
||||
}
|
||||
} else if (c == 017) {
|
||||
if (*data++)
|
||||
return FALSE;
|
||||
} else if (c >= 014 && c <= 016) {
|
||||
} else if (c >= 014 && c <= 017) {
|
||||
ins->oprs[c - 014].offset = (int8_t)*data++;
|
||||
ins->oprs[c - 014].segment |= SEG_SIGNED;
|
||||
} else if (c >= 020 && c <= 022) {
|
||||
} else if (c >= 020 && c <= 023) {
|
||||
ins->oprs[c - 020].offset = *data++;
|
||||
} else if (c >= 024 && c <= 026) {
|
||||
} else if (c >= 024 && c <= 027) {
|
||||
ins->oprs[c - 024].offset = *data++;
|
||||
} else if (c >= 030 && c <= 032) {
|
||||
} else if (c >= 030 && c <= 033) {
|
||||
ins->oprs[c - 030].offset = getu16(data);
|
||||
data += 2;
|
||||
} else if (c >= 034 && c <= 036) {
|
||||
} else if (c >= 034 && c <= 037) {
|
||||
if (osize == 32) {
|
||||
ins->oprs[c - 034].offset = getu32(data);
|
||||
data += 4;
|
||||
@ -451,10 +448,10 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
}
|
||||
if (segsize != asize)
|
||||
ins->oprs[c - 034].addr_size = asize;
|
||||
} else if (c >= 040 && c <= 042) {
|
||||
} else if (c >= 040 && c <= 043) {
|
||||
ins->oprs[c - 040].offset = getu32(data);
|
||||
data += 4;
|
||||
} else if (c >= 044 && c <= 046) {
|
||||
} else if (c >= 044 && c <= 047) {
|
||||
switch (asize) {
|
||||
case 16:
|
||||
ins->oprs[c - 044].offset = getu16(data);
|
||||
@ -471,18 +468,18 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
}
|
||||
if (segsize != asize)
|
||||
ins->oprs[c - 044].addr_size = asize;
|
||||
} else if (c >= 050 && c <= 052) {
|
||||
} else if (c >= 050 && c <= 053) {
|
||||
ins->oprs[c - 050].offset = gets8(data++);
|
||||
ins->oprs[c - 050].segment |= SEG_RELATIVE;
|
||||
} else if (c >= 054 && c <= 056) {
|
||||
} else if (c >= 054 && c <= 057) {
|
||||
ins->oprs[c - 054].offset = getu64(data);
|
||||
data += 8;
|
||||
} else if (c >= 060 && c <= 062) {
|
||||
} else if (c >= 060 && c <= 063) {
|
||||
ins->oprs[c - 060].offset = gets16(data);
|
||||
data += 2;
|
||||
ins->oprs[c - 060].segment |= SEG_RELATIVE;
|
||||
ins->oprs[c - 060].segment &= ~SEG_32BIT;
|
||||
} else if (c >= 064 && c <= 066) {
|
||||
} else if (c >= 064 && c <= 067) {
|
||||
if (osize == 16) {
|
||||
ins->oprs[c - 064].offset = getu16(data);
|
||||
data += 2;
|
||||
@ -498,30 +495,33 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
(ins->oprs[c - 064].type & ~SIZE_MASK)
|
||||
| ((osize == 16) ? BITS16 : BITS32);
|
||||
}
|
||||
} else if (c >= 070 && c <= 072) {
|
||||
} else if (c >= 070 && c <= 073) {
|
||||
ins->oprs[c - 070].offset = getu32(data);
|
||||
data += 4;
|
||||
ins->oprs[c - 070].segment |= SEG_32BIT | SEG_RELATIVE;
|
||||
} else if (c >= 0100 && c < 0130) {
|
||||
} else if (c >= 0100 && c < 0140) {
|
||||
int modrm = *data++;
|
||||
ins->oprs[c & 07].basereg = ((modrm >> 3)&7)+
|
||||
(ins->rex & REX_R ? 8 : 0);
|
||||
ins->oprs[c & 07].segment |= SEG_RMREG;
|
||||
data = do_ea(data, modrm, asize, segsize,
|
||||
&ins->oprs[(c >> 3) & 07], ins->rex);
|
||||
} else if (c >= 0130 && c <= 0132) {
|
||||
ins->oprs[c - 0130].offset = getu16(data);
|
||||
} else if (c >= 0140 && c <= 0143) {
|
||||
ins->oprs[c - 0140].offset = getu16(data);
|
||||
data += 2;
|
||||
} else if (c >= 0140 && c <= 0142) {
|
||||
ins->oprs[c - 0140].offset = getu32(data);
|
||||
} else if (c >= 0150 && c <= 0153) {
|
||||
ins->oprs[c - 0150].offset = getu32(data);
|
||||
data += 4;
|
||||
} else if (c == 0170) {
|
||||
if (*data++)
|
||||
return FALSE;
|
||||
} else if (c >= 0200 && c <= 0277) {
|
||||
int modrm = *data++;
|
||||
if (((modrm >> 3) & 07) != (c & 07))
|
||||
return FALSE; /* spare field doesn't match up */
|
||||
data = do_ea(data, modrm, asize, segsize,
|
||||
&ins->oprs[(c >> 3) & 07], ins->rex);
|
||||
} else if (c >= 0300 && c <= 0302) {
|
||||
} else if (c >= 0300 && c <= 0303) {
|
||||
a_used = TRUE;
|
||||
} else if (c == 0310) {
|
||||
if (asize != 16)
|
||||
|
162
insns.dat
162
insns.dat
@ -47,14 +47,14 @@ ADC reg_eax,imm \321\1\x15\41 386,SM
|
||||
ADC reg_rax,sbyte \321\1\x83\202\15 X64,SM,ND
|
||||
ADC reg_rax,imm \321\1\x15\41 X64,SM
|
||||
ADC rm8,imm \300\1\x80\202\21 8086,SM
|
||||
ADC rm16,imm \320\300\134\1\x81\202\131 8086,SM
|
||||
ADC rm32,imm \321\300\144\1\x81\202\141 386,SM
|
||||
ADC rm64,imm \324\300\144\1\x81\202\141 X64,SM
|
||||
ADC rm16,imm \320\300\145\1\x81\202\141 8086,SM
|
||||
ADC rm32,imm \321\300\155\1\x81\202\151 386,SM
|
||||
ADC rm64,imm \324\300\155\1\x81\202\151 X64,SM
|
||||
ADC mem,imm8 \300\1\x80\202\21 8086,SM
|
||||
ADC mem,imm16 \320\300\134\1\x81\202\131 8086,SM
|
||||
ADC mem,imm32 \321\300\144\1\x81\202\141 386,SM
|
||||
ADD mem,reg8 \300\17\101 8086,SM
|
||||
ADD reg8,reg8 \17\101 8086
|
||||
ADC mem,imm16 \320\300\145\1\x81\202\141 8086,SM
|
||||
ADC mem,imm32 \321\300\155\1\x81\202\151 386,SM
|
||||
ADD mem,reg8 \300\170\101 8086,SM
|
||||
ADD reg8,reg8 \170\101 8086
|
||||
ADD mem,reg16 \320\300\1\x01\101 8086,SM
|
||||
ADD reg16,reg16 \320\1\x01\101 8086
|
||||
ADD mem,reg32 \321\300\1\x01\101 386,SM
|
||||
@ -80,12 +80,12 @@ ADD reg_eax,imm \321\1\x05\41 386,SM
|
||||
ADD reg_rax,sbyte \321\1\x83\200\15 X64,SM,ND
|
||||
ADD reg_rax,imm \323\1\x05\41 X64,SM
|
||||
ADD rm8,imm \300\1\x80\200\21 8086,SM
|
||||
ADD rm16,imm \320\300\134\1\x81\200\131 8086,SM
|
||||
ADD rm32,imm \321\300\144\1\x81\200\141 386,SM
|
||||
ADD rm64,imm \324\300\144\1\x81\200\141 X64,SM
|
||||
ADD rm16,imm \320\300\145\1\x81\200\141 8086,SM
|
||||
ADD rm32,imm \321\300\155\1\x81\200\151 386,SM
|
||||
ADD rm64,imm \324\300\155\1\x81\200\151 X64,SM
|
||||
ADD mem,imm8 \300\1\x80\200\21 8086,SM
|
||||
ADD mem,imm16 \320\300\134\1\x81\200\131 8086,SM
|
||||
ADD mem,imm32 \321\300\144\1\x81\200\141 386,SM
|
||||
ADD mem,imm16 \320\300\145\1\x81\200\141 8086,SM
|
||||
ADD mem,imm32 \321\300\155\1\x81\200\151 386,SM
|
||||
AND mem,reg8 \300\1\x20\101 8086,SM
|
||||
AND reg8,reg8 \1\x20\101 8086
|
||||
AND mem,reg16 \320\300\1\x21\101 8086,SM
|
||||
@ -113,12 +113,12 @@ AND reg_eax,imm \321\1\x25\41 386,SM
|
||||
AND reg_rax,sbyte \321\1\x83\204\15 X64,SM,ND
|
||||
AND reg_rax,imm \324\1\x25\41 X64,SM
|
||||
AND rm8,imm \300\1\x80\204\21 8086,SM
|
||||
AND rm16,imm \320\300\134\1\x81\204\131 8086,SM
|
||||
AND rm32,imm \321\300\144\1\x81\204\141 386,SM
|
||||
AND rm64,imm \324\300\144\1\x81\204\141 X64,SM
|
||||
AND rm16,imm \320\300\145\1\x81\204\141 8086,SM
|
||||
AND rm32,imm \321\300\155\1\x81\204\151 386,SM
|
||||
AND rm64,imm \324\300\155\1\x81\204\151 X64,SM
|
||||
AND mem,imm8 \300\1\x80\204\21 8086,SM
|
||||
AND mem,imm16 \320\300\134\1\x81\204\131 8086,SM
|
||||
AND mem,imm32 \321\300\144\1\x81\204\141 386,SM
|
||||
AND mem,imm16 \320\300\145\1\x81\204\141 8086,SM
|
||||
AND mem,imm32 \321\300\155\1\x81\204\151 386,SM
|
||||
ARPL mem,reg16 \300\1\x63\101 286,PROT,SM,NOLONG
|
||||
ARPL reg16,reg16 \1\x63\101 286,PROT,NOLONG
|
||||
BOUND reg16,mem \320\301\1\x62\110 186,NOLONG
|
||||
@ -175,13 +175,13 @@ BTS rm32,imm \321\300\2\x0F\xBA\205\25 386,SB
|
||||
BTS rm64,imm \324\300\2\x0F\xBA\205\25 X64,SB
|
||||
CALL imm \322\1\xE8\64 8086
|
||||
CALL imm|near \322\1\xE8\64 8086
|
||||
CALL imm|far \322\1\x9A\34\37 8086,ND,NOLONG
|
||||
CALL imm|far \322\1\x9A\34\74 8086,ND,NOLONG
|
||||
CALL imm16 \320\1\xE8\64 8086
|
||||
CALL imm16|near \320\1\xE8\64 8086
|
||||
CALL imm16|far \320\1\x9A\34\37 8086,ND,NOLONG
|
||||
CALL imm16|far \320\1\x9A\34\74 8086,ND,NOLONG
|
||||
CALL imm32 \321\1\xE8\64 386
|
||||
CALL imm32|near \321\1\xE8\64 386
|
||||
CALL imm32|far \321\1\x9A\34\37 386,ND,NOLONG
|
||||
CALL imm32|far \321\1\x9A\34\74 386,ND,NOLONG
|
||||
CALL imm:imm \322\1\x9A\35\30 8086,NOLONG
|
||||
CALL imm16:imm \320\1\x9A\31\30 8086,NOLONG
|
||||
CALL imm:imm16 \320\1\x9A\31\30 8086,NOLONG
|
||||
@ -238,12 +238,12 @@ CMP reg_eax,imm \321\1\x3D\41 386,SM
|
||||
CMP reg_rax,sbyte \321\1\x83\207\15 X64,SM,ND
|
||||
CMP reg_rax,imm \321\1\x3D\41 X64,SM
|
||||
CMP rm8,imm \300\1\x80\207\21 8086,SM
|
||||
CMP rm16,imm \320\300\134\1\x81\207\131 8086,SM
|
||||
CMP rm32,imm \321\300\144\1\x81\207\141 386,SM
|
||||
CMP rm64,imm \324\300\144\1\x81\207\141 X64,SM
|
||||
CMP rm16,imm \320\300\145\1\x81\207\141 8086,SM
|
||||
CMP rm32,imm \321\300\155\1\x81\207\151 386,SM
|
||||
CMP rm64,imm \324\300\155\1\x81\207\151 X64,SM
|
||||
CMP mem,imm8 \300\1\x80\207\21 8086,SM
|
||||
CMP mem,imm16 \320\300\134\1\x81\207\131 8086,SM
|
||||
CMP mem,imm32 \321\300\144\1\x81\207\141 386,SM
|
||||
CMP mem,imm16 \320\300\145\1\x81\207\141 8086,SM
|
||||
CMP mem,imm32 \321\300\155\1\x81\207\151 386,SM
|
||||
CMPSB void \335\1\xA6 8086
|
||||
CMPSD void \335\321\1\xA7 386
|
||||
CMPSQ void \335\324\1\xA7 X64
|
||||
@ -497,38 +497,38 @@ IMUL reg64,reg64 \324\2\x0F\xAF\110 X64
|
||||
IMUL reg16,mem,imm8 \320\301\1\x6B\110\16 186,SM
|
||||
IMUL reg16,mem,sbyte \320\301\1\x6B\110\16 186,SM,ND
|
||||
IMUL reg16,mem,imm16 \320\301\1\x69\110\32 186,SM
|
||||
IMUL reg16,mem,imm \320\301\135\1\x69\110\132 186,SM,ND
|
||||
IMUL reg16,mem,imm \320\301\146\1\x69\110\142 186,SM,ND
|
||||
IMUL reg16,reg16,imm8 \320\1\x6B\110\16 186
|
||||
IMUL reg16,reg16,sbyte \320\1\x6B\110\16 186,SM,ND
|
||||
IMUL reg16,reg16,imm16 \320\1\x69\110\32 186
|
||||
IMUL reg16,reg16,imm \320\135\1\x69\110\132 186,SM,ND
|
||||
IMUL reg16,reg16,imm \320\146\1\x69\110\142 186,SM,ND
|
||||
IMUL reg32,mem,imm8 \321\301\1\x6B\110\16 386,SM
|
||||
IMUL reg32,mem,sbyte \321\301\1\x6B\110\16 386,SM,ND
|
||||
IMUL reg32,mem,imm32 \321\301\1\x69\110\42 386,SM
|
||||
IMUL reg32,mem,imm \321\301\145\1\x69\110\142 386,SM,ND
|
||||
IMUL reg32,mem,imm \321\301\156\1\x69\110\152 386,SM,ND
|
||||
IMUL reg32,reg32,imm8 \321\1\x6B\110\16 386
|
||||
IMUL reg32,reg32,sbyte \321\1\x6B\110\16 386,SM,ND
|
||||
IMUL reg32,reg32,imm32 \321\1\x69\110\42 386
|
||||
IMUL reg32,reg32,imm \321\145\1\x69\110\142 386,SM,ND
|
||||
IMUL reg32,reg32,imm \321\156\1\x69\110\152 386,SM,ND
|
||||
IMUL reg64,mem,imm8 \324\301\1\x6B\110\16 X64,SM
|
||||
IMUL reg64,mem,sbyte \324\301\1\x6B\110\16 X64,SM,ND
|
||||
IMUL reg64,mem,imm32 \324\301\1\x69\110\42 X64,SM
|
||||
IMUL reg64,mem,imm \324\301\145\1\x69\110\142 X64,SM,ND
|
||||
IMUL reg64,mem,imm \324\301\156\1\x69\110\152 X64,SM,ND
|
||||
IMUL reg64,reg64,imm8 \324\1\x6B\110\16 X64
|
||||
IMUL reg64,reg64,sbyte \324\1\x6B\110\16 X64,SM,ND
|
||||
IMUL reg64,reg64,imm32 \324\1\x69\110\42 X64
|
||||
IMUL reg64,reg64,imm \324\145\1\x69\110\142 X64,SM,ND
|
||||
IMUL reg64,reg64,imm \324\156\1\x69\110\152 X64,SM,ND
|
||||
IMUL reg16,imm8 \320\1\x6B\100\15 186
|
||||
IMUL reg16,sbyte \320\1\x6B\100\15 186,SM,ND
|
||||
IMUL reg16,imm16 \320\1\x69\100\31 186
|
||||
IMUL reg16,imm \320\134\1\x69\100\131 186,SM,ND
|
||||
IMUL reg16,imm \320\145\1\x69\100\141 186,SM,ND
|
||||
IMUL reg32,imm8 \321\1\x6B\100\15 386
|
||||
IMUL reg32,sbyte \321\1\x6B\100\15 386,SM,ND
|
||||
IMUL reg32,imm32 \321\1\x69\100\41 386
|
||||
IMUL reg32,imm \321\144\1\x69\100\141 386,SM,ND
|
||||
IMUL reg32,imm \321\155\1\x69\100\151 386,SM,ND
|
||||
IMUL reg64,sbyte \324\1\x6B\100\15 X64,SM,ND
|
||||
IMUL reg64,imm32 \324\1\x69\100\41 X64
|
||||
IMUL reg64,imm \324\144\1\x69\100\141 X64,SM,ND
|
||||
IMUL reg64,imm \324\155\1\x69\100\151 X64,SM,ND
|
||||
IN reg_al,imm \1\xE4\25 8086,SB
|
||||
IN reg_ax,imm \320\1\xE5\25 8086,SB
|
||||
IN reg_eax,imm \321\1\xE5\25 386,SB
|
||||
@ -564,13 +564,13 @@ JMP imm|short \1\xEB\50 8086
|
||||
JMP imm \371\1\xEB\50 8086,ND
|
||||
JMP imm \322\1\xE9\64 8086
|
||||
JMP imm|near \322\1\xE9\64 8086,ND
|
||||
JMP imm|far \322\1\xEA\34\37 8086,ND,NOLONG
|
||||
JMP imm|far \322\1\xEA\34\74 8086,ND,NOLONG
|
||||
JMP imm16 \320\1\xE9\64 8086
|
||||
JMP imm16|near \320\1\xE9\64 8086,ND
|
||||
JMP imm16|far \320\1\xEA\34\37 8086,ND,NOLONG
|
||||
JMP imm16|far \320\1\xEA\34\74 8086,ND,NOLONG
|
||||
JMP imm32 \321\1\xE9\64 386
|
||||
JMP imm32|near \321\1\xE9\64 386,ND
|
||||
JMP imm32|far \321\1\xEA\34\37 386,ND,NOLONG
|
||||
JMP imm32|far \321\1\xEA\34\74 386,ND,NOLONG
|
||||
JMP imm:imm \322\1\xEA\35\30 8086,NOLONG
|
||||
JMP imm16:imm \320\1\xEA\31\30 8086,NOLONG
|
||||
JMP imm:imm16 \320\1\xEA\31\30 8086,NOLONG
|
||||
@ -618,9 +618,9 @@ LGDT mem \300\2\x0F\x01\202 286,PRIV
|
||||
LGS reg16,mem \320\301\2\x0F\xB5\110 386
|
||||
LGS reg32,mem \321\301\2\x0F\xB5\110 386
|
||||
LIDT mem \300\2\x0F\x01\203 286,PRIV
|
||||
LLDT mem \300\1\x0F\17\202 286,PROT,PRIV
|
||||
LLDT mem16 \300\1\x0F\17\202 286,PROT,PRIV
|
||||
LLDT reg16 \1\x0F\17\202 286,PROT,PRIV
|
||||
LLDT mem \300\1\x0F\170\202 286,PROT,PRIV
|
||||
LLDT mem16 \300\1\x0F\170\202 286,PROT,PRIV
|
||||
LLDT reg16 \1\x0F\170\202 286,PROT,PRIV
|
||||
LMSW mem \300\2\x0F\x01\206 286,PRIV
|
||||
LMSW mem16 \300\2\x0F\x01\206 286,PRIV
|
||||
LMSW reg16 \2\x0F\x01\206 286,PRIV
|
||||
@ -658,9 +658,9 @@ LSL reg64,mem \324\301\2\x0F\x03\110 X64,SM
|
||||
LSL reg64,reg64 \324\2\x0F\x03\110 X64,PROT
|
||||
LSS reg16,mem \320\301\2\x0F\xB2\110 386
|
||||
LSS reg32,mem \321\301\2\x0F\xB2\110 386
|
||||
LTR mem \300\1\x0F\17\203 286,PROT,PRIV
|
||||
LTR mem16 \300\1\x0F\17\203 286,PROT,PRIV,NOLONG
|
||||
LTR reg16 \1\x0F\17\203 286,PROT,PRIV,NOLONG
|
||||
LTR mem \300\1\x0F\170\203 286,PROT,PRIV
|
||||
LTR mem16 \300\1\x0F\170\203 286,PROT,PRIV,NOLONG
|
||||
LTR reg16 \1\x0F\170\203 286,PROT,PRIV,NOLONG
|
||||
MFENCE void \3\x0F\xAE\xF0 X64,AMD
|
||||
MONITOR void \3\x0F\x01\xC8 PRESCOTT
|
||||
MONITOR reg_eax,reg_ecx,reg_edx \3\x0F\x01\xC8 PRESCOTT,ND
|
||||
@ -788,12 +788,12 @@ OR reg_eax,imm \321\1\x0D\41 386,SM
|
||||
OR reg_rax,sbyte \321\1\x83\201\15 X64,SM,ND
|
||||
OR reg_rax,imm \321\1\x0D\41 X64,SM
|
||||
OR rm8,imm \300\1\x80\201\21 8086,SM
|
||||
OR rm16,imm \320\300\134\1\x81\201\131 8086,SM
|
||||
OR rm32,imm \321\300\144\1\x81\201\141 386,SM
|
||||
OR rm64,imm \324\300\144\1\x81\201\141 X64,SM
|
||||
OR rm16,imm \320\300\145\1\x81\201\141 8086,SM
|
||||
OR rm32,imm \321\300\155\1\x81\201\151 386,SM
|
||||
OR rm64,imm \324\300\155\1\x81\201\151 X64,SM
|
||||
OR mem,imm8 \300\1\x80\201\21 8086,SM
|
||||
OR mem,imm16 \320\300\134\1\x81\201\131 8086,SM
|
||||
OR mem,imm32 \321\300\144\1\x81\201\141 386,SM
|
||||
OR mem,imm16 \320\300\145\1\x81\201\141 8086,SM
|
||||
OR mem,imm32 \321\300\155\1\x81\201\151 386,SM
|
||||
OUT imm,reg_al \1\xE6\24 8086,SB
|
||||
OUT imm,reg_ax \320\1\xE7\24 8086,SB
|
||||
OUT imm,reg_eax \321\1\xE7\24 386,SB
|
||||
@ -987,9 +987,9 @@ PUSH reg_dess \6 8086,NOLONG
|
||||
PUSH reg_fsgs \1\x0F\7 386
|
||||
PUSH imm8 \1\x6A\14 186
|
||||
PUSH sbyte \1\x6A\14 186,ND
|
||||
PUSH imm16 \320\133\1\x68\130 186
|
||||
PUSH imm32 \321\143\1\x68\140 386,NOLONG
|
||||
PUSH imm64 \321\143\1\x68\140 X64
|
||||
PUSH imm16 \320\144\1\x68\140 186
|
||||
PUSH imm32 \321\154\1\x68\150 386,NOLONG
|
||||
PUSH imm64 \321\154\1\x68\150 X64
|
||||
PUSH imm \1\x68\34 186
|
||||
PUSHA void \322\1\x60 186,NOLONG
|
||||
PUSHAD void \321\1\x60 386,NOLONG
|
||||
@ -1121,12 +1121,12 @@ SBB reg_eax,imm \321\1\x1D\41 386,SM
|
||||
SBB reg_rax,sbyte \321\1\x83\203\15 X64,SM,ND
|
||||
SBB reg_rax,imm \321\1\x1D\41 X64,SM
|
||||
SBB rm8,imm \300\1\x80\203\21 8086,SM
|
||||
SBB rm16,imm \320\300\134\1\x81\203\131 8086,SM
|
||||
SBB rm32,imm \321\300\144\1\x81\203\141 386,SM
|
||||
SBB rm64,imm \324\300\144\1\x81\203\141 X64,SM
|
||||
SBB rm16,imm \320\300\145\1\x81\203\141 8086,SM
|
||||
SBB rm32,imm \321\300\155\1\x81\203\151 386,SM
|
||||
SBB rm64,imm \324\300\155\1\x81\203\151 X64,SM
|
||||
SBB mem,imm8 \300\1\x80\203\21 8086,SM
|
||||
SBB mem,imm16 \320\300\134\1\x81\203\131 8086,SM
|
||||
SBB mem,imm32 \321\300\144\1\x81\203\141 386,SM
|
||||
SBB mem,imm16 \320\300\145\1\x81\203\141 8086,SM
|
||||
SBB mem,imm32 \321\300\155\1\x81\203\151 386,SM
|
||||
SCASB void \335\1\xAE 8086
|
||||
SCASD void \335\321\1\xAF 386
|
||||
SCASQ void \335\324\1\xAF X64
|
||||
@ -1182,10 +1182,10 @@ SHRD reg32,reg32,reg_cl \321\2\x0F\xAD\101 386
|
||||
SHRD mem,reg64,reg_cl \300\324\2\x0F\xAD\101 X64,SM
|
||||
SHRD reg64,reg64,reg_cl \324\2\x0F\xAD\101 X64
|
||||
SIDT mem \300\2\x0F\x01\201 286
|
||||
SLDT mem \300\1\x0F\17\200 286
|
||||
SLDT mem16 \300\1\x0F\17\200 286
|
||||
SLDT reg16 \320\1\x0F\17\200 286
|
||||
SLDT reg32 \321\1\x0F\17\200 386
|
||||
SLDT mem \300\1\x0F\170\200 286
|
||||
SLDT mem16 \300\1\x0F\170\200 286
|
||||
SLDT reg16 \320\1\x0F\170\200 286
|
||||
SLDT reg32 \321\1\x0F\170\200 386
|
||||
SKINIT void \3\x0F\x01\xDE X64
|
||||
SMI void \1\xF1 386,UNDOC
|
||||
SMINT void \2\x0F\x38 P6,CYRIX
|
||||
@ -1203,11 +1203,11 @@ STOSB void \1\xAA 8086
|
||||
STOSD void \321\1\xAB 386
|
||||
STOSQ void \324\1\xAB X64
|
||||
STOSW void \320\1\xAB 8086
|
||||
STR mem \300\1\x0F\17\201 286,PROT
|
||||
STR mem16 \300\1\x0F\17\201 286,PROT
|
||||
STR reg16 \320\1\x0F\17\201 286,PROT
|
||||
STR reg32 \321\1\x0F\17\201 386,PROT
|
||||
STR reg64 \324\1\x0F\17\201 X64
|
||||
STR mem \300\1\x0F\170\201 286,PROT
|
||||
STR mem16 \300\1\x0F\170\201 286,PROT
|
||||
STR reg16 \320\1\x0F\170\201 286,PROT
|
||||
STR reg32 \321\1\x0F\170\201 386,PROT
|
||||
STR reg64 \324\1\x0F\170\201 X64
|
||||
SUB mem,reg8 \300\1\x28\101 8086,SM
|
||||
SUB reg8,reg8 \1\x28\101 8086
|
||||
SUB mem,reg16 \320\300\1\x29\101 8086,SM
|
||||
@ -1235,12 +1235,12 @@ SUB reg_eax,imm \321\1\x2D\41 386,SM
|
||||
SUB reg_rax,sbyte \321\1\x83\205\15 X64,SM,ND
|
||||
SUB reg_rax,imm \321\1\x2D\41 X64,SM
|
||||
SUB rm8,imm \300\1\x80\205\21 8086,SM
|
||||
SUB rm16,imm \320\300\134\1\x81\205\131 8086,SM
|
||||
SUB rm32,imm \321\300\144\1\x81\205\141 386,SM
|
||||
SUB rm64,imm \324\300\144\1\x81\205\141 X64,SM
|
||||
SUB rm16,imm \320\300\145\1\x81\205\141 8086,SM
|
||||
SUB rm32,imm \321\300\155\1\x81\205\151 386,SM
|
||||
SUB rm64,imm \324\300\155\1\x81\205\151 X64,SM
|
||||
SUB mem,imm8 \300\1\x80\205\21 8086,SM
|
||||
SUB mem,imm16 \320\300\134\1\x81\205\131 8086,SM
|
||||
SUB mem,imm32 \321\300\144\1\x81\205\141 386,SM
|
||||
SUB mem,imm16 \320\300\145\1\x81\205\141 8086,SM
|
||||
SUB mem,imm32 \321\300\155\1\x81\205\151 386,SM
|
||||
SVDC mem80,reg_sreg \300\2\x0F\x78\101 486,CYRIX,SMM
|
||||
SVLDT mem80 \300\2\x0F\x7A\200 486,CYRIX,SMM
|
||||
SVTS mem80 \300\2\x0F\x7C\200 486,CYRIX,SMM
|
||||
@ -1287,12 +1287,12 @@ UMOV reg16,mem \320\301\2\x0F\x13\110 386,UNDOC,SM
|
||||
UMOV reg16,reg16 \320\2\x0F\x13\110 386,UNDOC
|
||||
UMOV reg32,mem \321\301\2\x0F\x13\110 386,UNDOC,SM
|
||||
UMOV reg32,reg32 \321\2\x0F\x13\110 386,UNDOC
|
||||
VERR mem \300\1\x0F\17\204 286,PROT
|
||||
VERR mem16 \300\1\x0F\17\204 286,PROT
|
||||
VERR reg16 \1\x0F\17\204 286,PROT
|
||||
VERW mem \300\1\x0F\17\205 286,PROT
|
||||
VERW mem16 \300\1\x0F\17\205 286,PROT
|
||||
VERW reg16 \1\x0F\17\205 286,PROT
|
||||
VERR mem \300\1\x0F\170\204 286,PROT
|
||||
VERR mem16 \300\1\x0F\170\204 286,PROT
|
||||
VERR reg16 \1\x0F\170\204 286,PROT
|
||||
VERW mem \300\1\x0F\170\205 286,PROT
|
||||
VERW mem16 \300\1\x0F\170\205 286,PROT
|
||||
VERW reg16 \1\x0F\170\205 286,PROT
|
||||
WAIT void \1\x9B 8086
|
||||
FWAIT void \1\x9B 8086
|
||||
WBINVD void \2\x0F\x09 486,PRIV
|
||||
@ -1360,12 +1360,12 @@ XOR reg_eax,imm \321\1\x35\41 386,SM
|
||||
XOR reg_rax,sbyte \321\1\x83\206\15 X64,SM,ND
|
||||
XOR reg_rax,imm \321\1\x35\41 X64,SM
|
||||
XOR rm8,imm \300\1\x80\206\21 8086,SM
|
||||
XOR rm16,imm \320\300\134\1\x81\206\131 8086,SM
|
||||
XOR rm32,imm \321\300\144\1\x81\206\141 386,SM
|
||||
XOR rm64,imm \324\300\144\1\x81\206\141 X64,SM
|
||||
XOR rm16,imm \320\300\145\1\x81\206\141 8086,SM
|
||||
XOR rm32,imm \321\300\155\1\x81\206\151 386,SM
|
||||
XOR rm64,imm \324\300\155\1\x81\206\151 X64,SM
|
||||
XOR mem,imm8 \300\1\x80\206\21 8086,SM
|
||||
XOR mem,imm16 \320\300\134\1\x81\206\131 8086,SM
|
||||
XOR mem,imm32 \321\300\144\1\x81\206\141 386,SM
|
||||
XOR mem,imm16 \320\300\145\1\x81\206\141 8086,SM
|
||||
XOR mem,imm32 \321\300\155\1\x81\206\151 386,SM
|
||||
XSTORE void \3\x0F\xA7\xC0 P6,CYRIX
|
||||
CMOVcc reg16,mem \320\301\1\x0F\330\x40\110 P6,SM
|
||||
CMOVcc reg16,reg16 \320\1\x0F\330\x40\110 P6
|
||||
|
18
insns.h
18
insns.h
@ -9,7 +9,7 @@
|
||||
#ifndef NASM_INSNS_H
|
||||
#define NASM_INSNS_H
|
||||
|
||||
#include "insnsi.h" /* instruction opcode enum */
|
||||
#include "nasm.h"
|
||||
|
||||
/* max length of any instruction, register name etc. */
|
||||
#if MAX_INSLEN > 9 /* MAX_INSLEN defined in insnsi.h */
|
||||
@ -21,7 +21,7 @@
|
||||
struct itemplate {
|
||||
enum opcode opcode; /* the token, passed from "parser.c" */
|
||||
int operands; /* number of operands */
|
||||
int32_t opd[3]; /* bit flags for operand types */
|
||||
int32_t opd[MAX_OPERANDS]; /* bit flags for operand types */
|
||||
const char *code; /* the code it assembles to */
|
||||
uint32_t flags; /* some flags */
|
||||
};
|
||||
@ -66,12 +66,14 @@ extern const struct itemplate * const * const itable[];
|
||||
#define IF_SM2 0x00000002UL /* size match first two operands */
|
||||
#define IF_SB 0x00000004UL /* unsized operands can't be non-byte */
|
||||
#define IF_SW 0x00000008UL /* unsized operands can't be non-word */
|
||||
#define IF_SD 0x00000010UL /* unsized operands can't be non-dword */
|
||||
#define IF_SQ 0x00000020UL /* unsized operands can't be non-qword */
|
||||
#define IF_AR0 0x00000040UL /* SB, SW, SD applies to argument 0 */
|
||||
#define IF_AR1 0x00000080UL /* SB, SW, SD applies to argument 1 */
|
||||
#define IF_AR2 0x000000C0UL /* SB, SW, SD applies to argument 2 */
|
||||
#define IF_ARMASK 0x000000C0UL /* mask for unsized argument spec */
|
||||
#define IF_SD 0x0000000CUL /* unsized operands can't be non-dword */
|
||||
#define IF_SQ 0x00000010UL /* unsized operands can't be non-qword */
|
||||
#define IF_SMASK 0x0000001CUL /* mask for unsized argument size */
|
||||
#define IF_AR0 0x00000020UL /* SB, SW, SD applies to argument 0 */
|
||||
#define IF_AR1 0x00000040UL /* SB, SW, SD applies to argument 1 */
|
||||
#define IF_AR2 0x00000060UL /* SB, SW, SD applies to argument 2 */
|
||||
#define IF_AR3 0x00000080UL /* SB, SW, SD applies to argument 2 */
|
||||
#define IF_ARMASK 0x000000E0UL /* mask for unsized argument spec */
|
||||
#define IF_PRIV 0x00000100UL /* it's a privileged instruction */
|
||||
#define IF_SMM 0x00000200UL /* it's only valid in SMM */
|
||||
#define IF_PROT 0x00000400UL /* it's protected mode only */
|
||||
|
69
insns.pl
69
insns.pl
@ -203,45 +203,52 @@ if ( !defined($output) || $output eq 'n' ) {
|
||||
printf STDERR "Done: %d instructions\n", $insns;
|
||||
|
||||
sub format {
|
||||
local ($opcode, $operands, $codes, $flags) = @_;
|
||||
local $num, $nd = 0;
|
||||
my ($opcode, $operands, $codes, $flags) = @_;
|
||||
my $num, $nd = 0;
|
||||
|
||||
return (undef, undef) if $operands eq "ignore";
|
||||
|
||||
# format the operands
|
||||
$operands =~ s/:/|colon,/g;
|
||||
$operands =~ s/mem(\d+)/mem|bits$1/g;
|
||||
$operands =~ s/mem/memory/g;
|
||||
$operands =~ s/memory_offs/mem_offs/g;
|
||||
$operands =~ s/imm(\d+)/imm|bits$1/g;
|
||||
$operands =~ s/imm/immediate/g;
|
||||
$operands =~ s/rm(\d+)/rm_gpr|bits$1/g;
|
||||
$operands =~ s/mmxrm/rm_mmx/g;
|
||||
$operands =~ s/xmmrm/rm_xmm/g;
|
||||
$num = 3;
|
||||
$operands = '0,0,0', $num = 0 if $operands eq 'void';
|
||||
$operands .= ',0', $num-- while $operands !~ /,.*,/;
|
||||
$operands =~ tr/a-z/A-Z/;
|
||||
|
||||
# format the flags
|
||||
$flags =~ s/,/|IF_/g;
|
||||
$flags =~ s/(\|IF_ND|IF_ND\|)//, $nd = 1 if $flags =~ /IF_ND/;
|
||||
$flags = "IF_" . $flags;
|
||||
|
||||
("{I_$opcode, $num, {$operands}, \"$codes\", $flags},", $nd);
|
||||
return (undef, undef) if $operands eq "ignore";
|
||||
|
||||
# format the operands
|
||||
$operands =~ s/:/|colon,/g;
|
||||
$operands =~ s/mem(\d+)/mem|bits$1/g;
|
||||
$operands =~ s/mem/memory/g;
|
||||
$operands =~ s/memory_offs/mem_offs/g;
|
||||
$operands =~ s/imm(\d+)/imm|bits$1/g;
|
||||
$operands =~ s/imm/immediate/g;
|
||||
$operands =~ s/rm(\d+)/rm_gpr|bits$1/g;
|
||||
$operands =~ s/mmxrm/rm_mmx/g;
|
||||
$operands =~ s/xmmrm/rm_xmm/g;
|
||||
if ($operands eq 'void') {
|
||||
@ops = ();
|
||||
} else {
|
||||
@ops = split(/\,/, $operands);
|
||||
}
|
||||
$num = scalar(@ops);
|
||||
while (scalar(@ops) < 4) {
|
||||
push(@ops, '0');
|
||||
}
|
||||
$operands = join(',', @ops);
|
||||
$operands =~ tr/a-z/A-Z/;
|
||||
|
||||
# format the flags
|
||||
$flags =~ s/,/|IF_/g;
|
||||
$flags =~ s/(\|IF_ND|IF_ND\|)//, $nd = 1 if $flags =~ /IF_ND/;
|
||||
$flags = "IF_" . $flags;
|
||||
|
||||
("{I_$opcode, $num, {$operands}, \"$codes\", $flags},", $nd);
|
||||
}
|
||||
|
||||
# Here we determine the range of possible starting bytes for a given
|
||||
# instruction. We need only consider the codes:
|
||||
# \1 \2 \3 mean literal bytes, of course
|
||||
# \4 \5 \6 \7 mean PUSH/POP of segment registers: special case
|
||||
# \10 \11 \12 mean byte plus register value
|
||||
# \17 means byte zero
|
||||
# \1[0123] mean byte plus register value
|
||||
# \170 means byte zero
|
||||
# \330 means byte plus condition code
|
||||
# \0 or \340 mean give up and return empty set
|
||||
sub startbyte {
|
||||
local ($codes) = @_;
|
||||
local $word, @range;
|
||||
my ($codes) = @_;
|
||||
my $word, @range;
|
||||
|
||||
while (1) {
|
||||
die "couldn't get code in '$codes'" if $codes !~ /^(\\[^\\]+)(\\.*)?$/;
|
||||
@ -251,8 +258,8 @@ sub startbyte {
|
||||
return (0xA1, 0xA9) if $word eq "\\5";
|
||||
return (0x06, 0x0E, 0x16, 0x1E) if $word eq "\\6";
|
||||
return (0xA0, 0xA8) if $word eq "\\7";
|
||||
$start=hex $1, $r=8, last if $word =~ /^\\1[012]$/ && $codes =~/^\\x(..)/;
|
||||
return (0) if $word eq "\\17";
|
||||
$start=hex $1, $r=8, last if $word =~ /^\\1[0123]$/ && $codes =~/^\\x(..)/;
|
||||
return (0) if $word eq "\\170";
|
||||
$start=hex $1, $r=16, last if $word =~ /^\\330$/ && $codes =~ /^\\x(..)/;
|
||||
return () if $word eq "\\0" || $word eq "\\340";
|
||||
}
|
||||
|
3
nasm.h
3
nasm.h
@ -607,6 +607,7 @@ typedef struct extop { /* extended operand */
|
||||
} extop;
|
||||
|
||||
#define MAXPREFIX 4
|
||||
#define MAX_OPERANDS 4
|
||||
|
||||
typedef struct { /* an instruction itself */
|
||||
char *label; /* the label defined, or NULL */
|
||||
@ -616,7 +617,7 @@ typedef struct { /* an instruction itself */
|
||||
enum ccode condition; /* the condition code, if Jcc/SETcc */
|
||||
int operands; /* how many operands? 0-3
|
||||
* (more if db et al) */
|
||||
operand oprs[3]; /* the operands, defined as above */
|
||||
operand oprs[MAX_OPERANDS]; /* the operands, defined as above */
|
||||
extop *eops; /* extended operands */
|
||||
int eops_float; /* true if DD and floating */
|
||||
int32_t times; /* repeat count (TIMES prefix) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user