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