Exemplo n.º 1
0
int32_t instr_group_5_ff_inc(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if ( i->modrm.mod != 3 )
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* FF /0 
			 * Increment r/m word by 1
			 * INC r/m16 
			 */   
			uint16_t dst;
			MEM_WORD_READ(c, i->modrm.ea, &dst);

			INSTR_CALC_AND_SET_FLAGS(16, c, dst)

			MEM_WORD_WRITE(c, i->modrm.ea, dst);
		}
		else
		{
			/* FF /0 
			 * Increment r/m doubleword by 1
			 * INC r/m32 
			 */
			uint32_t dst;
			MEM_DWORD_READ(c, i->modrm.ea, &dst);

			INSTR_CALC_AND_SET_FLAGS(32, c, dst)

			MEM_DWORD_WRITE(c, i->modrm.ea, dst);
		}   
	}
	else
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* FF /0 
			 * Increment r/m word by 1
			 * INC r/m16 
			 */   
			INSTR_CALC_AND_SET_FLAGS(16, c, *c->reg16[i->modrm.rm])
		}
		else
		{
			/* FF /0 
			 * Increment r/m doubleword by 1
			 * INC r/m32 
			 */
			INSTR_CALC_AND_SET_FLAGS(32, c, c->reg[i->modrm.rm])
		}   
	}
	return 0;
}
Exemplo n.º 2
0
int32_t instr_group_5_ff_push(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if ( i->modrm.mod != 3 )
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* FF /6 
			 * Push r/m16    
			 * PUSH r/m16 
			 */
			uint16_t m16;
			MEM_WORD_READ(c,i->modrm.ea,&m16);
			PUSH_WORD(c, m16);
		}
		else
		{
			/* FF /6 
			 * Push r/m32    
			 * PUSH r/m32 
			 */
			uint32_t m32;
			MEM_DWORD_READ(c,i->modrm.ea,&m32);
			enum emu_segment oldseg = emu_memory_segment_get(c->mem);
			emu_memory_segment_select(c->mem, s_ss);
			PUSH_DWORD(c, m32);
			emu_memory_segment_select(c->mem, oldseg);

		}
	}
	else
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* FF /6 
			 * Push r/m16    
			 * PUSH r/m16 
			 */
			PUSH_WORD(c, *c->reg16[i->modrm.rm]);
		}
		else
		{
			/* FF /6 
			 * Push r/m32    
			 * PUSH r/m32 
			 */
			PUSH_DWORD(c, c->reg[i->modrm.rm]);
		}
	}
	return 0;
}
Exemplo n.º 3
0
int32_t instr_mov_8b(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if( i->prefixes & PREFIX_OPSIZE )
	{
		/* 8B /r  
		 * Move r/m16 to r16                                
		 * MOV r16,r/m16    
		 */																		 

		if( i->modrm.mod != 3 )
		{
			MEM_WORD_READ(c, i->modrm.ea, c->reg16[i->modrm.opc]);
			//TRACK_INIT_REG16(c->instr, i->modrm.opc);
		}
		else
		{
			*c->reg16[i->modrm.opc] = *c->reg16[i->modrm.rm];
		}
	}
	else
	{
		/* 8B /r  
		 * Move r/m32 to r32                                
		 * MOV r32,r/m32    
		 */																		 

		if( i->modrm.mod != 3 )
		{
			MEM_DWORD_READ(c, i->modrm.ea, &c->reg[i->modrm.opc]);
			//TRACK_INIT_REG32(c->instr, i->modrm.opc);
		}
		else
		{
			c->reg[i->modrm.opc] = c->reg[i->modrm.rm];

			//TRACK_INIT_REG32(c->instr, i->modrm.opc);

			/*if ( c->tracking != NULL )
			{
				c->tracking->track.reg[i->modrm.opc] = c->tracking->track.reg[i->modrm.rm];
			}*/
		}
	}

	return 0;
}
Exemplo n.º 4
0
//dzzie 5.19.11 - http://pdos.csail.mit.edu/6.828/2004/readings/i386/MOVS.htm
int32_t instr_movs_a5(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if (i->prefixes & PREFIX_ADSIZE ) {
		UNIMPLEMENTED(c, SST);
		return 0;
    }

	uint8_t incSize = 0;

	if ( i->prefixes & PREFIX_OPSIZE ) //16bit
	{ 
		uint16_t tmp;
		MEM_WORD_READ(c, c->reg[esi], &tmp);
		MEM_WORD_WRITE(c, c->reg[edi], tmp);
		incSize = 2;
	}
	else{ //32bit
		uint32_t tmp2;
		MEM_DWORD_READ(c, c->reg[esi], &tmp2);
		MEM_DWORD_WRITE(c, c->reg[edi], tmp2);
		incSize = 4;
	}
	
	if (i->prefixes & PREFIX_F3)    /* rep prefix - Copy ECX bytes from DS:[ESI] to ES:[EDI] */
	{
		c->repeat_current_instr = false;
		if (c->reg[ecx] > 0 ){
			c->reg[ecx]--;
			c->repeat_current_instr = true;
		}else{
			return 0; //rep operation complete..do not adjust registers any more
		}
	} 

	if ( !CPU_FLAG_ISSET(c,f_df) ){ /* increment */
		c->reg[edi] += incSize;
		c->reg[esi] += incSize;
	} 
	else{							/* decrement */
		c->reg[edi] -= incSize;
		c->reg[esi] -= incSize;
	}

    return 0;
}
Exemplo n.º 5
0
int32_t instr_mov_a1(struct emu_cpu *c, struct emu_cpu_instruction *i)
{

	if ( i->prefixes & PREFIX_OPSIZE )
	{
		/* A1     
		 * Move word at (seg:offset) to AX                  
		 * MOV AX,moffs16*  
		 */                                                                      

		MEM_WORD_READ(c, i->disp, c->reg16[ax]);
	}
	else
	{
		/* A1     
		 * Move doubleword at (seg:offset) to EAX           
		 * MOV EAX,moffs32* 
		 */
		MEM_DWORD_READ(c, i->disp, &c->reg[eax]);
		
		//TRACK_INIT_REG32(c->instr, eax);
	}
	return 0;
}
Exemplo n.º 6
0
int32_t instr_imul_0f_af(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if ( i->modrm.mod != 3 )
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* 0F AF /r 
			 * word register <- word register * r/m word                      
			 * IMUL r16,r/m16      
			 */                                                                                              
			uint16_t m16;
			MEM_WORD_READ(c, i->modrm.ea, &m16);

			INSTR_CALC(16,
					   32,
					   c, 
					   *c->reg16[i->modrm.opc],
					   m16)

			*c->reg16[i->modrm.opc] = operation_result;

			uint8_t high;
			WORD_UPPER_TO_BYTE(high,operation_result);
			INSTR_SET_FLAGS(c,high);
		}
		else
		{
			/* 0F AF /r 
			 * doubleword register <- doubleword register * r/m doubleword                                                          
			 * IMUL r32,r/m32      
			 */
			uint32_t m32;
			MEM_DWORD_READ(c, i->modrm.ea, &m32);

			INSTR_CALC(32,
					   64,
					   c, 
					   c->reg[i->modrm.opc],
					   m32)

			c->reg[i->modrm.opc] = operation_result;

			uint16_t high;
			DWORD_UPPER_TO_WORD(high,operation_result);
			INSTR_SET_FLAGS(c,high);
		}
	}
	else
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* 0F AF /r 
			 * word register <- word register * r/m word                      
			 * IMUL r16,r/m16      
			 */                                                                                              
			INSTR_CALC(16,
					   32,
					   c, 
					   *c->reg16[i->modrm.opc],
					   *c->reg16[i->modrm.rm])

			*c->reg16[i->modrm.opc] = operation_result;

			uint8_t high;
			WORD_UPPER_TO_BYTE(high,operation_result);
			INSTR_SET_FLAGS(c,high);
		}
		else
		{
			/* 0F AF /r 
			 * doubleword register <- doubleword register * r/m doubleword                                                          
			 * IMUL r32,r/m32      
			 */
			INSTR_CALC(32,
					   64,
					   c, 
					   c->reg[i->modrm.opc],
					   c->reg[i->modrm.rm])

			c->reg[i->modrm.opc] = operation_result;

			uint16_t high;
			DWORD_UPPER_TO_WORD(high,operation_result);
			INSTR_SET_FLAGS(c,high);
		}
	}
	return 0;
}
Exemplo n.º 7
0
int32_t instr_group_2_d3_shr(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if ( i->modrm.mod != 3 )
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* D3 /5   
			 * Unsigned divide r/m16 by 2, CL times                  
			 * SHR r/m16,CL   
			 */
			uint16_t m16;
			MEM_WORD_READ(c, i->modrm.ea, &m16);
			INSTR_CALC_AND_SET_FLAGS(16,
									 c,
									 m16,
									 *c->reg8[cl]);

			MEM_WORD_WRITE(c, i->modrm.ea, m16);        
		}
		else
		{
			/* D3 /5   
			 * Unsigned divide r/m32 by 2, CL times            
			 * SHR r/m32,CL   
			 */
			uint32_t m32;
			MEM_DWORD_READ(c, i->modrm.ea, &m32);
			INSTR_CALC_AND_SET_FLAGS(32,
									 c,
									 m32,
									 *c->reg8[cl]);

			MEM_DWORD_WRITE(c, i->modrm.ea, m32);       
		}
	}
	else
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* D3 /5   
			 * Unsigned divide r/m16 by 2, CL times                  
			 * SHR r/m16,CL   
			 */
			INSTR_CALC_AND_SET_FLAGS(16,
									 c,
									 *c->reg16[i->modrm.rm],
									 *c->reg8[cl]);
		}
		else
		{
			/* D3 /5   
			 * Unsigned divide r/m32 by 2, CL times            
			 * SHR r/m32,CL   
			 */
			INSTR_CALC_AND_SET_FLAGS(32,
									 c,
									 c->reg[i->modrm.rm],
									 *c->reg8[cl]);
		}
	}

	return 0;
}
Exemplo n.º 8
0
int32_t instr_group_3_f7_not(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if ( i->modrm.mod != 3 )
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* F7 /2  
			 * Reverse each bit of r/m16
			 * NOT r/m16   
			 */
			uint16_t m16;
			MEM_WORD_READ(c, i->modrm.ea, &m16);
			INSTR_CALC_AND_SET_FLAGS(16,
									 c,
									 m16)
			MEM_WORD_WRITE(c, i->modrm.ea, m16);

		}
		else
		{
			/* F7 /2  
			 * Reverse each bit of r/m32
			 * NOT r/m32   
			 */
			uint32_t m32;
			MEM_DWORD_READ(c, i->modrm.ea, &m32);
			INSTR_CALC_AND_SET_FLAGS(32,
									 c,
									 m32)
			MEM_DWORD_WRITE(c, i->modrm.ea, m32);

		}
	}
	else
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* F7 /2  
			 * Reverse each bit of r/m16
			 * NOT r/m16   
			 */   
			INSTR_CALC_AND_SET_FLAGS(16,
									 c,
									 *c->reg16[i->modrm.rm])

		}
		else
		{
			/* F7 /2  
			 * Reverse each bit of r/m32
			 * NOT r/m32   
			 */
			INSTR_CALC_AND_SET_FLAGS(32,
									 c,
									 c->reg[i->modrm.rm])

		}

	}
	return 0;
}
Exemplo n.º 9
0
int32_t instr_group_2_d3_rcl(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if ( i->modrm.mod != 3 )
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* D3 /2    
			 * Rotate 17 bits (CF,r/m16) left CL times
			 * RCL r/m16,CL   
			 */
			uint16_t m16;
			MEM_WORD_READ(c, i->modrm.ea, &m16);
			INSTR_CALC_AND_SET_FLAGS(16,
									 c,
									 m16,
									 *c->reg8[cl]);

			MEM_WORD_WRITE(c, i->modrm.ea, m16);        
		}
		else
		{
			/* D3 /2    
			 * Rotate 33 bits (CF,r/m32) left CL times
			 * RCL r/m32,CL
			 */
			uint32_t m32;
			MEM_DWORD_READ(c, i->modrm.ea, &m32);
			INSTR_CALC_AND_SET_FLAGS(32,
									 c,
									 m32,
									 *c->reg8[cl]);

			MEM_DWORD_WRITE(c, i->modrm.ea, m32);       
		}
	}
	else
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* D3 /2    
			 * Rotate 17 bits (CF,r/m16) left CL times
			 * RCL r/m16,CL   
			 */
			INSTR_CALC_AND_SET_FLAGS(16,
									 c,
									 *c->reg16[i->modrm.rm],
									 *c->reg8[cl]);
		}
		else
		{
			/* D3 /2    
			 * Rotate 33 bits (CF,r/m32) left CL times
			 * RCL r/m32,CL
			 */
			INSTR_CALC_AND_SET_FLAGS(32,
									 c,
									 c->reg[i->modrm.rm],
									 *c->reg8[cl]);
		}
	}


	return 0;
}
Exemplo n.º 10
0
int32_t instr_group_5_ff_call(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if( i->modrm.opc == 2 )
	{
		PUSH_DWORD(c, c->eip);
		
		if( i->modrm.mod != 3 )
		{
			if( i->prefixes & PREFIX_OPSIZE )
			{
				/* FF /2  
				 * CALL r/m16    
				 * Call near, absolute indirect, address given in r/m16   
				 */

				uint16_t disp;
				MEM_WORD_READ(c, i->modrm.ea, &disp);
				
				c->eip = disp;

				SOURCE_NORM_POS(c->instr, c->eip);
			}
			else
			{
				/* FF /2  
				 * CALL r/m32    
				 * Call near, absolute indirect, address given in r/m32   
				 */

				uint32_t disp;
				MEM_DWORD_READ(c, i->modrm.ea, &disp);
				
				c->eip = disp;

				SOURCE_NORM_POS(c->instr, c->eip);
			}
		}
		else
		{
			if( i->prefixes & PREFIX_OPSIZE )
			{
				/* FF /2  
				 * CALL r/m16    
				 * Call near, absolute indirect, address given in r/m16   
				 */

				c->eip = *c->reg16[i->modrm.rm];

				SOURCE_NORM_POS(c->instr, c->eip);
				TRACK_NEED_REG16(c->instr, i->modrm.rm);
			}
			else
			{
				/* FF /2  
				 * CALL r/m32    
				 * Call near, absolute indirect, address given in r/m32   
				 */

				c->eip = c->reg[i->modrm.rm];

				SOURCE_NORM_POS(c->instr, c->eip);
				TRACK_NEED_REG32(c->instr, i->modrm.rm);
			}
		}
	}
	else
	{
		/* FF /3  
		 * CALL m16:16   
		 * Call far, absolute indirect, address given in m16:16  
		 */

		/* FF /3  
		 * CALL m16:32   
		 * Call far, absolute indirect, address given in m16:32  
		 */

		UNIMPLEMENTED(c, SST);

	}

	return 0;
}
Exemplo n.º 11
0
int32_t instr_group_2_d1_sal(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if ( i->modrm.mod != 3 )
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* D1 /4	
			 * Multiply r/m16 by 2, once               
			 * SAL r/m16,1    
			 */
			uint16_t m16;
			MEM_WORD_READ(c, i->modrm.ea, &m16);
			INSTR_CALC_AND_SET_FLAGS(16,
									 c,
									 m16,
									 1);

			MEM_WORD_WRITE(c, i->modrm.ea, m16);        

		}
		else
		{
			/* D1 /4	
			 * Multiply r/m32 by 2, once             
			 * SAL r/m32,1    
			 */
			uint32_t m32;
			MEM_DWORD_READ(c, i->modrm.ea, &m32);
			INSTR_CALC_AND_SET_FLAGS(32,
									 c,
									 m32,
									 1);
			MEM_DWORD_WRITE(c, i->modrm.ea, m32);       
		}
	}
	else
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* D1 /4	
			 * Multiply r/m16 by 2, once               
			 * SAL r/m16,1    
			 */
			INSTR_CALC_AND_SET_FLAGS(16,
									 c,
									 *c->reg16[i->modrm.rm],
									 1);

		}
		else
		{
			/* D1 /4	
			 * Multiply r/m32 by 2, once             
			 * SAL r/m32,1    
			 */
			INSTR_CALC_AND_SET_FLAGS(32,
									 c,
									 c->reg[i->modrm.rm],
									 1);

		}
	}

	return 0;
}
Exemplo n.º 12
0
int32_t instr_imul_69(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if ( i->modrm.mod != 3 )
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* 69 /r iw 
			 * word register <- r/m16 * immediate word                        
			 * IMUL r16,imm16      
			 *
			 * word register <- r/m16 * immediate word                        
			 * IMUL r16,r/m16,imm16         
			 */
#if BYTE_ORDER == BIG_ENDIAN
			int16_t sexd;
			bcopy(i->imm16, &sexd, 2);
#else
			int16_t sexd = (int16_t)*i->imm16;
#endif
			uint16_t m16;
			MEM_WORD_READ(c, i->modrm.ea, &m16);

			INSTR_CALC(16,
					   32,
					   c, 
					   m16,
					   sexd) 

			*c->reg16[i->modrm.opc] = operation_result;

			uint8_t high;
			WORD_UPPER_TO_BYTE(high,operation_result);
			INSTR_SET_FLAGS(c,high);

		}
		else
		{
			/* 69 /r id 
			 * doubleword register <- r/m32 * immediate doubleword            
			 * IMUL r32,imm32      
			 *
			 * doubleword register <- r/m32 * immediate doubleword            
			 * IMUL r32,r/m32,imm32         
			 */
			int32_t sexd = (int32_t)i->imm;

			uint32_t m32;
			MEM_DWORD_READ(c, i->modrm.ea, &m32);

			INSTR_CALC(32,
					   64,
					   c, 
					   m32,
					   sexd)

			c->reg[i->modrm.opc] = operation_result;

			uint32_t high;
			QWORD_UPPER_TO_DWORD(high,operation_result);
			INSTR_SET_FLAGS(c,high);
		}
	}
	else
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* 69 /r iw 
			 * word register <- r/m16 * immediate word                        
			 * IMUL r16,imm16      
			 *
			 * word register <- r/m16 * immediate word                        
			 * IMUL r16,r/m16,imm16         
			 */
#if BYTE_ORDER == BIG_ENDIAN
			int16_t sexd;
			bcopy(i->imm16, &sexd, 2);
#else
			int16_t sexd = (int16_t)*i->imm16;
#endif


			INSTR_CALC(16,
					   32,
					   c, 
					   *c->reg16[i->modrm.rm],
					   sexd)
			*c->reg16[i->modrm.opc] = operation_result;

			uint8_t high;
			WORD_UPPER_TO_BYTE(high,operation_result);
			INSTR_SET_FLAGS(c,high);
		}
		else
		{
			/* 69 /r id 
			 * doubleword register <- r/m32 * immediate doubleword            
			 * IMUL r32,imm32      
			 *
			 * doubleword register <- r/m32 * immediate doubleword            
			 * IMUL r32,r/m32,imm32         
			 */ 
			int32_t sexd = (int32_t)i->imm;

			INSTR_CALC(32,
					   64,
					   c, 
					   c->reg[i->modrm.rm],
					   sexd)
			c->reg[i->modrm.opc] = operation_result;

			uint32_t high;
			QWORD_UPPER_TO_DWORD(high,operation_result);
			INSTR_SET_FLAGS(c,high);

		}

	}

	return 0;
}
Exemplo n.º 13
0
int32_t instr_group_3_f7_imul(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if ( i->modrm.mod != 3 )
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* F7 /5    
			 * DX:AX <- AX * r/m word                                         
			 * IMUL r/m16          
			 */
			uint16_t m16;
			MEM_WORD_READ(c, i->modrm.ea, &m16);
			INSTR_CALC(16,
					   32,
					   c,
					   *c->reg16[al],
					   m16)

			DWORD_UPPER_TO_WORD(*c->reg16[dx],operation_result);
			DWORD_LOWER_TO_WORD(*c->reg16[ax],operation_result);

			INSTR_SET_FLAGS(c,*c->reg16[dx]);
		}
		else
		{
			/* F7 /5    
			 * EDX:EAX <- EAX * r/m doubleword                                
			 * IMUL r/m32          
			 */      
			uint32_t m32;
			MEM_DWORD_READ(c, i->modrm.ea, &m32);
			INSTR_CALC(32,
					   64,
					   c,
					   c->reg[eax],
					   m32)

			QWORD_UPPER_TO_DWORD(c->reg[edx],operation_result);
			QWORD_LOWER_TO_DWORD(c->reg[eax],operation_result);

			INSTR_SET_FLAGS(c,c->reg[edx]);

		}
	}
	else
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* F7 /5    
			 * DX:AX <- AX * r/m word                                         
			 * IMUL r/m16          
			 */
			INSTR_CALC(16,
					   32,
					   c,
					   *c->reg16[al],
					   *c->reg16[i->modrm.rm])
			DWORD_UPPER_TO_WORD(*c->reg16[dx],operation_result);
			DWORD_LOWER_TO_WORD(*c->reg16[ax],operation_result);

			INSTR_SET_FLAGS(c,*c->reg16[dx]);

		}
		else
		{
			/* F7 /5    
			 * EDX:EAX <- EAX * r/m doubleword                                
			 * IMUL r/m32          
			 */                                                                                              
			INSTR_CALC(32,
					   64,
					   c,
					   c->reg[eax],
					   c->reg[i->modrm.rm])

			QWORD_UPPER_TO_DWORD(c->reg[edx],operation_result);
			QWORD_LOWER_TO_DWORD(c->reg[eax],operation_result);

			INSTR_SET_FLAGS(c,c->reg[edx]);
		}
	}
	return 0;
}
Exemplo n.º 14
0
int32_t instr_imul_6b(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if ( i->modrm.mod != 3 )
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* 6B /r ib 
			 * word register <- m16 * sign-extended immediate byte          
			 * IMUL r16,m16,imm8 
			 */
			int16_t sexd = (int8_t)*i->imm8;

			uint16_t m16;
			MEM_WORD_READ(c, i->modrm.ea, &m16);

			INSTR_CALC(16,
					   32,
					   c, 
					   m16,
					   sexd) 

			*c->reg16[i->modrm.opc] = operation_result;

			uint8_t high;
			WORD_UPPER_TO_BYTE(high,operation_result);
			INSTR_SET_FLAGS(c,high);
		}
		else
		{
			/* 6B /r ib 
			 * word register <- m16 * sign-extended immediate byte          
			 * IMUL r16,m16,imm8 
			 */

			int32_t sexd = (int8_t)*i->imm8;

			uint32_t m32;
			MEM_DWORD_READ(c, i->modrm.ea, &m32);

			INSTR_CALC(32, 
					   64,
					   c, 
					   m32,
					   sexd)

			c->reg[i->modrm.opc] = operation_result;

			uint32_t high;
			QWORD_UPPER_TO_DWORD(high,operation_result);
			INSTR_SET_FLAGS(c,high);
		}
	}
	else
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* 6B /r ib 
			 * word register <- r16 * sign-extended immediate byte          
			 * IMUL r16,r16,imm8 
			 *
			 * word register <- word register * sign-extended immediate byte                                                                
			 * IMUL r16,imm8       
			 */
			int16_t sexd = (int8_t)*i->imm8;

			INSTR_CALC(16,
					   32,
					   c, 
					   *c->reg16[i->modrm.rm],
					   sexd)
			*c->reg16[i->modrm.opc] = operation_result;

			uint8_t high;
			WORD_UPPER_TO_BYTE(high,operation_result);
			INSTR_SET_FLAGS(c,high);
		}
		else
		{
			/* 6B /r ib 
			 * doubleword register <- r32 * sign-extended immediate byte                                                                
			 * IMUL r32,r32,imm8 
			 *
			 * doubleword register <- doubleword register * sign-extended immediate byte                                             
			 * IMUL r32,imm8       
			 */
			int32_t sexd = (int8_t)*i->imm8;

			INSTR_CALC(32,
					   64,
					   c, 
					   c->reg[i->modrm.rm],
					   sexd)
			c->reg[i->modrm.opc] = operation_result;

			uint32_t high;
			QWORD_UPPER_TO_DWORD(high,operation_result);
			INSTR_SET_FLAGS(c,high);
		}
	}
	return 0;
}
Exemplo n.º 15
0
int32_t instr_group_2_c1_sar(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if ( i->modrm.mod != 3 )
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* C1 /7 ib 
			 * Signed divide* r/m16 by 2, imm8 times
			 * SAR r/m16,imm8 
			 */
			uint16_t m16;
			MEM_WORD_READ(c, i->modrm.ea, &m16);
			INSTR_CALC_AND_SET_FLAGS(16,
									 c,
									 m16,
									 *i->imm8);

			MEM_WORD_WRITE(c, i->modrm.ea, m16);        

		}
		else
		{
			/* C1 /7 ib 
			 * Signed divide* r/m32 by 2, imm8 times
			 * SAR r/m32,imm8 
			 */
			uint32_t m32;
			MEM_DWORD_READ(c, i->modrm.ea, &m32);
			INSTR_CALC_AND_SET_FLAGS(32,
									 c,
									 m32,
									 *i->imm8);
			MEM_DWORD_WRITE(c, i->modrm.ea, m32);       
		}
	}
	else
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* C1 /7 ib 
			 * Signed divide* r/m16 by 2, imm8 times
			 * SAR r/m16,imm8 
			 */
			INSTR_CALC_AND_SET_FLAGS(16,
									 c,
									 *c->reg16[i->modrm.rm],
									 *i->imm8);

		}
		else
		{
			/* C1 /7 ib 
			 * Signed divide* r/m32 by 2, imm8 times
			 * SAR r/m32,imm8 
			 */
			INSTR_CALC_AND_SET_FLAGS(32,
									 c,
									 c->reg[i->modrm.rm],
									 *i->imm8);

		}
	}

	return 0;
}
Exemplo n.º 16
0
int32_t instr_group_5_ff_jmp(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if( i->modrm.opc == 4 )
	{
		if( i->modrm.mod != 3 )
		{
			if( i->prefixes & PREFIX_OPSIZE )
			{
				/* FF /4  
				 * Jump near, absolute indirect, address given in r/m16                   
				 * JMP r/m16    
				 */

				uint16_t disp;
				MEM_WORD_READ(c, i->modrm.ea, &disp);
				
				c->eip = disp;

				SOURCE_NORM_POS(c->instr, c->eip);
			}
			else
			{
				/* FF /4  
				 * Jump near, absolute indirect, address given in r/m32                   
				 * JMP r/m32    
				 */

				uint32_t disp;
				MEM_DWORD_READ(c, i->modrm.ea, &disp);
				
				c->eip = disp;

				SOURCE_NORM_POS(c->instr, c->eip);
			}
		}
		else
		{
			if( i->prefixes & PREFIX_OPSIZE )
			{
				/* FF /4  
				 * Jump near, absolute indirect, address given in r/m16                   
				 * JMP r/m16    
				 */

				c->eip = *c->reg16[i->modrm.rm];

				SOURCE_NORM_POS(c->instr, c->eip);
				//TRACK_NEED_REG16(c->instr, i->modrm.rm);
			}
			else
			{
				/* FF /4  
				 * Jump near, absolute indirect, address given in r/m32                   
				 * JMP r/m32    
				 */

				c->eip = c->reg[i->modrm.rm];

				SOURCE_NORM_POS(c->instr, c->eip);
				//TRACK_NEED_REG32(c->instr, i->modrm.rm);
			}
		}
	}
	else /* /5 */
	{
		/* unneeded */
		/* FF /5  
		 * Jump far, absolute indirect, address given in m16:16                   
		 * JMP m16:16   
		 */


		/* FF /5  
		 * Jump far, absolute indirect, address given in m16:32                   
		 * JMP m16:32   
		 */

		UNIMPLEMENTED(c, SST);

	}

	return 0;
}
Exemplo n.º 17
0
int32_t instr_group_2_d1_rcr(struct emu_cpu *c, struct emu_cpu_instruction *i)
{
	if ( i->modrm.mod != 3 )
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* D1 /3	 
			 * Rotate 17 bits (CF,r/m16) right once              
			 * RCR r/m16,1    
			 */
			uint16_t m16;
			MEM_WORD_READ(c, i->modrm.ea, &m16);
			INSTR_CALC_AND_SET_FLAGS(16,
									 c,
									 m16,
									 1);

			MEM_WORD_WRITE(c, i->modrm.ea, m16);        

		}
		else
		{
			/* D1 /3	 
			 * Rotate 33 bits (CF,r/m32) right once                     
			 * RCR r/m32,1    
			 */
			uint32_t m32;
			MEM_DWORD_READ(c, i->modrm.ea, &m32);
			INSTR_CALC_AND_SET_FLAGS(32,
									 c,
									 m32,
									 1);
			MEM_DWORD_WRITE(c, i->modrm.ea, m32);       
		}
	}
	else
	{
		if ( i->prefixes & PREFIX_OPSIZE )
		{
			/* D1 /3	 
			 * Rotate 17 bits (CF,r/m16) right once              
			 * RCR r/m16,1    
			 */
			INSTR_CALC_AND_SET_FLAGS(16,
									 c,
									 *c->reg16[i->modrm.rm],
									 1);

		}
		else
		{
			/* D1 /3	 
			 * Rotate 33 bits (CF,r/m32) right once                     
			 * RCR r/m32,1    
			 */
			INSTR_CALC_AND_SET_FLAGS(32,
									 c,
									 c->reg[i->modrm.rm],
									 1);

		}
	}

	return 0;
}
Exemplo n.º 18
0
int32_t instr_lods_ad(struct emu_cpu *c, struct emu_cpu_instruction *i)
{

	if ( i->prefixes & PREFIX_OPSIZE )
	{

		/* AD 
		 * Load word at address DS:(E)SI into AX
		 * LODS m16 
		 */

		/* AD 
		 * Load word at address DS:(E)SI into AX
		 * LODSW    
		 */
		if ( i->prefixes & PREFIX_ADSIZE )
		{
//        	MEM_WORD_READ(c, c->reg16[si], c->reg16[ax]);
			UNIMPLEMENTED(c, SST);
		}
		else
		{
			MEM_WORD_READ(c, c->reg[esi], c->reg16[ax]);
			if (CPU_FLAG_ISSET(c,f_df))
			{ /* decrement */
				c->reg[esi] -= 2;
			}else
			{ /* increment */
				c->reg[esi] += 2;
			}
		}

	}
	else
	{

		/* AD 
		 * Load doubleword at address DS:(E)SI into EAX
		 * LODS m32 
		 */


		/* AD
		 * Load doubleword at address DS:(E)SI into EAX
		 * LODSD    
		 */
		if ( i->prefixes & PREFIX_ADSIZE )
		{
//			MEM_DWORD_READ(c, c->reg16[si], &c->reg[eax]);
			UNIMPLEMENTED(c, SST);

		}
		else
		{
			MEM_DWORD_READ(c, c->reg[esi], &c->reg[eax]);
			if (CPU_FLAG_ISSET(c,f_df))
			{ /* decrement */
				c->reg[esi] -= 4;
			}else
			{ /* increment */
				c->reg[esi] += 4;
			}

			//TRACK_INIT_REG32(c->instr, eax);
		}
	}

	return 0;
}