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:
		
							
								
								
									
										46
									
								
								assemble.c
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								assemble.c
									
									
									
									
									
								
							| @@ -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: | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								disasm.c
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								disasm.c
									
									
									
									
									
								
							| @@ -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; | ||||||
|   | |||||||
							
								
								
									
										38
									
								
								insns.dat
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								insns.dat
									
									
									
									
									
								
							| @@ -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 | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								insns.pl
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								insns.pl
									
									
									
									
									
								
							| @@ -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 | ||||||
|   | |||||||
| @@ -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 | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user