0
0
mirror of https://github.com/netwide-assembler/nasm.git synced 2025-10-10 00:25:06 -04:00

New opcodes to deal with 8-bit immediate sign extended to opsize

New opcodes to deal with 8-bit immediates which are then sign-extended
to the operand size.  These allow us to warn appropriately.
Not sure I'm using these in all the proper places; need audit of all
uses of the \14..\17 opcodes.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin
2008-10-06 23:40:31 -07:00
parent 94cacf8ea9
commit c1377e9a98
5 changed files with 73 additions and 25 deletions

View File

@@ -29,13 +29,13 @@
* \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..\73 - a long relative operand, from operand 0..3
* \74..\77 - a word constant, from the _segment_ part of 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.
* \140..\143 - an immediate word or signed byte for operand 0..3
* \144..\147 - or 2 (s-field) into opcode byte if operand 0..3
* is a signed byte rather than a word. Opcode byte follows.
* \150..\153 - an immediate dword or signed byte for operand 0..3
* \150..\153 - an immediate dword or signed byte for operand 0..3
* \154..\157 - or 2 (s-field) into opcode byte if operand 0..3
* is a signed byte rather than a dword. Opcode byte follows.
* \160..\163 - this instruction uses DREX rather than REX, with the
@@ -70,6 +70,8 @@
* [ww] ww = 3 for W used as REX.W
*
*
* \274..\277 - a signed byte immediate operand, from operand 0..3,
* which is to be extended to the operand size.
* \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
* \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
* \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
@@ -989,6 +991,12 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
ins->vex_m = *codes++;
ins->vex_wlp = *codes++;
break;
case 0274:
case 0275:
case 0276:
case 0277:
length++;
break;
case 0300:
case 0301:
case 0302:
@@ -1625,6 +1633,44 @@ static void gencode(int32_t segment, int64_t offset, int bits,
}
break;
case 0274:
case 0275:
case 0276:
case 0277:
{
uint64_t uv, um;
int s;
if (ins->rex & REX_W)
s = 64;
else if (ins->prefixes[PPS_OSIZE] == P_O16)
s = 16;
else if (ins->prefixes[PPS_OSIZE] == P_O32)
s = 32;
else
s = bits;
um = (uint64_t)2 << (s-1);
uv = opx->offset;
if (uv > 127 && uv < (uint64_t)-128 &&
(uv < um-128 || uv > um-1)) {
errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
"signed byte value exceeds bounds");
}
if (opx->segment != NO_SEG) {
data = um;
out(offset, segment, &data, OUT_ADDRESS, 1,
opx->segment, opx->wrt);
} else {
bytes[0] = um;
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
NO_SEG);
}
offset += 1;
break;
}
case 0300:
case 0301:
case 0302:

View File

@@ -482,6 +482,7 @@ static int matches(const struct itemplate *t, uint8_t *data,
}
case4(014):
case4(0274):
opx->offset = (int8_t)*data++;
opx->segment |= SEG_SIGNED;
break;

View File

@@ -87,9 +87,9 @@ ADD reg32,mem \321\1\x03\110 386,SM
ADD reg32,reg32 \321\1\x03\110 386
ADD reg64,mem \324\1\x03\110 X64,SM
ADD reg64,reg64 \324\1\x03\110 X64
ADD rm16,imm8 \320\1\x83\200\15 8086
ADD rm32,imm8 \321\1\x83\200\15 386
ADD rm64,imm8 \324\1\x83\200\15 X64
ADD rm16,imm8 \320\1\x83\200\275 8086
ADD rm32,imm8 \321\1\x83\200\275 386
ADD rm64,imm8 \324\1\x83\200\275 X64
ADD reg_al,imm \1\x04\21 8086,SM
ADD reg_ax,imm \320\1\x05\31 8086,SM
ADD reg_eax,imm \321\1\x05\41 386,SM
@@ -242,9 +242,9 @@ CMP reg32,mem \321\1\x3B\110 386,SM
CMP reg32,reg32 \321\1\x3B\110 386
CMP reg64,mem \324\1\x3B\110 X64,SM
CMP reg64,reg64 \324\1\x3B\110 X64
CMP rm16,imm8 \320\1\x83\207\15 8086
CMP rm32,imm8 \321\1\x83\207\15 386
CMP rm64,imm8 \324\1\x83\207\15 X64
CMP rm16,imm8 \320\1\x83\207\275 8086
CMP rm32,imm8 \321\1\x83\207\275 386
CMP rm64,imm8 \324\1\x83\207\275 X64
CMP reg_al,imm \1\x3C\21 8086,SM
CMP reg_ax,imm \320\1\x3D\31 8086,SM
CMP reg_eax,imm \321\1\x3D\41 386,SM
@@ -840,9 +840,9 @@ OR reg32,mem \321\1\x0B\110 386,SM
OR reg32,reg32 \321\1\x0B\110 386
OR reg64,mem \324\1\x0B\110 X64,SM
OR reg64,reg64 \324\1\x0B\110 X64
OR rm16,imm8 \320\1\x83\201\15 8086
OR rm32,imm8 \321\1\x83\201\15 386
OR rm64,imm8 \324\1\x83\201\15 X64
OR rm16,imm8 \320\1\x83\201\275 8086
OR rm32,imm8 \321\1\x83\201\275 386
OR rm64,imm8 \324\1\x83\201\275 X64
OR reg_al,imm \1\x0C\21 8086,SM
OR reg_ax,imm \320\1\x0D\31 8086,SM
OR reg_eax,imm \321\1\x0D\41 386,SM
@@ -973,7 +973,7 @@ PUSH rm64 \323\1\xFF\206 X64
PUSH reg_cs \6 8086,NOLONG
PUSH reg_dess \6 8086,NOLONG
PUSH reg_fsgs \1\x0F\7 386
PUSH imm8 \1\x6A\14 186
PUSH imm8 \1\x6A\274 186
PUSH imm16 \320\144\x68\140 186,AR0,SZ
PUSH imm32 \321\154\x68\150 386,NOLONG,AR0,SZ
PUSH imm32 \321\154\x68\150 386,NOLONG,SD
@@ -1092,9 +1092,9 @@ SBB reg32,mem \321\1\x1B\110 386,SM
SBB reg32,reg32 \321\1\x1B\110 386
SBB reg64,mem \324\1\x1B\110 X64,SM
SBB reg64,reg64 \324\1\x1B\110 X64
SBB rm16,imm8 \320\1\x83\203\15 8086
SBB rm32,imm8 \321\1\x83\203\15 386
SBB rm64,imm8 \324\1\x83\203\15 X64
SBB rm16,imm8 \320\1\x83\203\275 8086
SBB rm32,imm8 \321\1\x83\203\275 386
SBB rm64,imm8 \324\1\x83\203\275 X64
SBB reg_al,imm \1\x1C\21 8086,SM
SBB reg_ax,imm \320\1\x1D\31 8086,SM
SBB reg_eax,imm \321\1\x1D\41 386,SM
@@ -1205,9 +1205,9 @@ SUB reg32,mem \321\1\x2B\110 386,SM
SUB reg32,reg32 \321\1\x2B\110 386
SUB reg64,mem \324\1\x2B\110 X64,SM
SUB reg64,reg64 \324\1\x2B\110 X64
SUB rm16,imm8 \320\1\x83\205\15 8086
SUB rm32,imm8 \321\1\x83\205\15 386
SUB rm64,imm8 \324\1\x83\205\15 X64
SUB rm16,imm8 \320\1\x83\205\275 8086
SUB rm32,imm8 \321\1\x83\205\275 386
SUB rm64,imm8 \324\1\x83\205\275 X64
SUB reg_al,imm \1\x2C\21 8086,SM
SUB reg_ax,imm \320\1\x2D\31 8086,SM
SUB reg_eax,imm \321\1\x2D\41 386,SM
@@ -1333,9 +1333,9 @@ XOR reg32,mem \321\1\x33\110 386,SM
XOR reg32,reg32 \321\1\x33\110 386
XOR reg64,mem \324\1\x33\110 X64,SM
XOR reg64,reg64 \324\1\x33\110 X64
XOR rm16,imm8 \320\1\x83\206\15 8086
XOR rm32,imm8 \321\1\x83\206\15 386
XOR rm64,imm8 \324\1\x83\206\15 X64
XOR rm16,imm8 \320\1\x83\206\275 8086
XOR rm32,imm8 \321\1\x83\206\275 386
XOR rm64,imm8 \324\1\x83\206\275 X64
XOR reg_al,imm \1\x34\21 8086,SM
XOR reg_ax,imm \320\1\x35\31 8086,SM
XOR reg_eax,imm \321\1\x35\41 386,SM

View File

@@ -670,6 +670,8 @@ sub byte_code_compile($) {
push(@codes, 024+$oppos{'i'});
} elsif ($op eq 'iw') { # imm16
push(@codes, 030+$oppos{'i'});
} elsif ($op eq 'ibx') { # imm8 sign-extended to opsize
push(@codes, 0274+$oppos{'i'});
} elsif ($op eq 'iwd') { # imm16 or imm32, depending on opsize
push(@codes, 034+$oppos{'i'});
} elsif ($op eq 'id') { # imm32

View File

@@ -14,14 +14,14 @@
%endif
push -1
push 0ffffh
push byte 0FFFFh ; XXX - inappropriate
push byte 0FFFFh
add ax,0FFFFh
%if WARN
add ax,0FFFFFFFFh
%endif
add ax,-1
add ax,byte 0FFFFh ; XXX - inappropriate
add ax,byte 0FFFFh
%if WARN
add ax,byte 0FFFFFFFFh
%endif
@@ -32,7 +32,7 @@
add cx,0FFFFFFFFh
%endif
add cx,-1
add cx,byte 0FFFFh ; XXX - inappropriate
add cx,byte 0FFFFh
%if WARN
add cx,byte 0FFFFFFFFh
%endif
@@ -87,4 +87,3 @@
push byte 0ffffffffh
%endif
push byte -1