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 * \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 * assembly mode or the operand-size override on the operand
* \70..\73 - a long relative operand, from operand 0..3 * \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 * \1ab - a ModRM, calculated on EA in operand a, with the spare
* field the register value of operand b. * field the register value of operand b.
* \140..\143 - an immediate word or signed byte for operand 0..3 * \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 * \144..\147 - or 2 (s-field) into opcode byte if operand 0..3
* is a signed byte rather than a word. Opcode byte follows. * 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 * \154..\157 - or 2 (s-field) into opcode byte if operand 0..3
* is a signed byte rather than a dword. Opcode byte follows. * is a signed byte rather than a dword. Opcode byte follows.
* \160..\163 - this instruction uses DREX rather than REX, with the * \160..\163 - this instruction uses DREX rather than REX, with the
@@ -70,6 +70,8 @@
* [ww] ww = 3 for W used as REX.W * [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. * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
* \311 - indicates fixed 32-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. * \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_m = *codes++;
ins->vex_wlp = *codes++; ins->vex_wlp = *codes++;
break; break;
case 0274:
case 0275:
case 0276:
case 0277:
length++;
break;
case 0300: case 0300:
case 0301: case 0301:
case 0302: case 0302:
@@ -1625,6 +1633,44 @@ static void gencode(int32_t segment, int64_t offset, int bits,
} }
break; 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 0300:
case 0301: case 0301:
case 0302: case 0302:

View File

@@ -482,6 +482,7 @@ static int matches(const struct itemplate *t, uint8_t *data,
} }
case4(014): case4(014):
case4(0274):
opx->offset = (int8_t)*data++; opx->offset = (int8_t)*data++;
opx->segment |= SEG_SIGNED; opx->segment |= SEG_SIGNED;
break; 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 reg32,reg32 \321\1\x03\110 386
ADD reg64,mem \324\1\x03\110 X64,SM ADD reg64,mem \324\1\x03\110 X64,SM
ADD reg64,reg64 \324\1\x03\110 X64 ADD reg64,reg64 \324\1\x03\110 X64
ADD rm16,imm8 \320\1\x83\200\15 8086 ADD rm16,imm8 \320\1\x83\200\275 8086
ADD rm32,imm8 \321\1\x83\200\15 386 ADD rm32,imm8 \321\1\x83\200\275 386
ADD rm64,imm8 \324\1\x83\200\15 X64 ADD rm64,imm8 \324\1\x83\200\275 X64
ADD reg_al,imm \1\x04\21 8086,SM ADD reg_al,imm \1\x04\21 8086,SM
ADD reg_ax,imm \320\1\x05\31 8086,SM ADD reg_ax,imm \320\1\x05\31 8086,SM
ADD reg_eax,imm \321\1\x05\41 386,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 reg32,reg32 \321\1\x3B\110 386
CMP reg64,mem \324\1\x3B\110 X64,SM CMP reg64,mem \324\1\x3B\110 X64,SM
CMP reg64,reg64 \324\1\x3B\110 X64 CMP reg64,reg64 \324\1\x3B\110 X64
CMP rm16,imm8 \320\1\x83\207\15 8086 CMP rm16,imm8 \320\1\x83\207\275 8086
CMP rm32,imm8 \321\1\x83\207\15 386 CMP rm32,imm8 \321\1\x83\207\275 386
CMP rm64,imm8 \324\1\x83\207\15 X64 CMP rm64,imm8 \324\1\x83\207\275 X64
CMP reg_al,imm \1\x3C\21 8086,SM CMP reg_al,imm \1\x3C\21 8086,SM
CMP reg_ax,imm \320\1\x3D\31 8086,SM CMP reg_ax,imm \320\1\x3D\31 8086,SM
CMP reg_eax,imm \321\1\x3D\41 386,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 reg32,reg32 \321\1\x0B\110 386
OR reg64,mem \324\1\x0B\110 X64,SM OR reg64,mem \324\1\x0B\110 X64,SM
OR reg64,reg64 \324\1\x0B\110 X64 OR reg64,reg64 \324\1\x0B\110 X64
OR rm16,imm8 \320\1\x83\201\15 8086 OR rm16,imm8 \320\1\x83\201\275 8086
OR rm32,imm8 \321\1\x83\201\15 386 OR rm32,imm8 \321\1\x83\201\275 386
OR rm64,imm8 \324\1\x83\201\15 X64 OR rm64,imm8 \324\1\x83\201\275 X64
OR reg_al,imm \1\x0C\21 8086,SM OR reg_al,imm \1\x0C\21 8086,SM
OR reg_ax,imm \320\1\x0D\31 8086,SM OR reg_ax,imm \320\1\x0D\31 8086,SM
OR reg_eax,imm \321\1\x0D\41 386,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_cs \6 8086,NOLONG
PUSH reg_dess \6 8086,NOLONG PUSH reg_dess \6 8086,NOLONG
PUSH reg_fsgs \1\x0F\7 386 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 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,AR0,SZ
PUSH imm32 \321\154\x68\150 386,NOLONG,SD 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 reg32,reg32 \321\1\x1B\110 386
SBB reg64,mem \324\1\x1B\110 X64,SM SBB reg64,mem \324\1\x1B\110 X64,SM
SBB reg64,reg64 \324\1\x1B\110 X64 SBB reg64,reg64 \324\1\x1B\110 X64
SBB rm16,imm8 \320\1\x83\203\15 8086 SBB rm16,imm8 \320\1\x83\203\275 8086
SBB rm32,imm8 \321\1\x83\203\15 386 SBB rm32,imm8 \321\1\x83\203\275 386
SBB rm64,imm8 \324\1\x83\203\15 X64 SBB rm64,imm8 \324\1\x83\203\275 X64
SBB reg_al,imm \1\x1C\21 8086,SM SBB reg_al,imm \1\x1C\21 8086,SM
SBB reg_ax,imm \320\1\x1D\31 8086,SM SBB reg_ax,imm \320\1\x1D\31 8086,SM
SBB reg_eax,imm \321\1\x1D\41 386,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 reg32,reg32 \321\1\x2B\110 386
SUB reg64,mem \324\1\x2B\110 X64,SM SUB reg64,mem \324\1\x2B\110 X64,SM
SUB reg64,reg64 \324\1\x2B\110 X64 SUB reg64,reg64 \324\1\x2B\110 X64
SUB rm16,imm8 \320\1\x83\205\15 8086 SUB rm16,imm8 \320\1\x83\205\275 8086
SUB rm32,imm8 \321\1\x83\205\15 386 SUB rm32,imm8 \321\1\x83\205\275 386
SUB rm64,imm8 \324\1\x83\205\15 X64 SUB rm64,imm8 \324\1\x83\205\275 X64
SUB reg_al,imm \1\x2C\21 8086,SM SUB reg_al,imm \1\x2C\21 8086,SM
SUB reg_ax,imm \320\1\x2D\31 8086,SM SUB reg_ax,imm \320\1\x2D\31 8086,SM
SUB reg_eax,imm \321\1\x2D\41 386,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 reg32,reg32 \321\1\x33\110 386
XOR reg64,mem \324\1\x33\110 X64,SM XOR reg64,mem \324\1\x33\110 X64,SM
XOR reg64,reg64 \324\1\x33\110 X64 XOR reg64,reg64 \324\1\x33\110 X64
XOR rm16,imm8 \320\1\x83\206\15 8086 XOR rm16,imm8 \320\1\x83\206\275 8086
XOR rm32,imm8 \321\1\x83\206\15 386 XOR rm32,imm8 \321\1\x83\206\275 386
XOR rm64,imm8 \324\1\x83\206\15 X64 XOR rm64,imm8 \324\1\x83\206\275 X64
XOR reg_al,imm \1\x34\21 8086,SM XOR reg_al,imm \1\x34\21 8086,SM
XOR reg_ax,imm \320\1\x35\31 8086,SM XOR reg_ax,imm \320\1\x35\31 8086,SM
XOR reg_eax,imm \321\1\x35\41 386,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'}); push(@codes, 024+$oppos{'i'});
} elsif ($op eq 'iw') { # imm16 } elsif ($op eq 'iw') { # imm16
push(@codes, 030+$oppos{'i'}); 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 } elsif ($op eq 'iwd') { # imm16 or imm32, depending on opsize
push(@codes, 034+$oppos{'i'}); push(@codes, 034+$oppos{'i'});
} elsif ($op eq 'id') { # imm32 } elsif ($op eq 'id') { # imm32

View File

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