Changeset 41501 in vbox for trunk/src/VBox/Disassembler/testcase/tstDisasm-2.cpp
- Timestamp:
- May 30, 2012 3:58:23 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Disassembler/testcase/tstDisasm-2.cpp
r38636 r41501 108 108 109 109 /** 110 * Checks if the encoding of the current instruction is something111 * we can never get the assembler to produce.112 *113 * @returns true if it's odd, false if it isn't.114 * @param pCpu The disassembler output.115 */116 static bool MyDisasYasmFormatterIsOddEncoding(PMYDISSTATE pState)117 {118 /*119 * Mod rm + SIB: Check for duplicate EBP encodings that yasm won't use for very good reasons.120 */121 if ( pState->Cpu.addrmode != CPUMODE_16BIT ///@todo correct?122 && pState->Cpu.ModRM.Bits.Rm == 4123 && pState->Cpu.ModRM.Bits.Mod != 3)124 {125 /* No scaled index SIB (index=4), except for ESP. */126 if ( pState->Cpu.SIB.Bits.Index == 4127 && pState->Cpu.SIB.Bits.Base != 4)128 return true;129 130 /* EBP + displacement */131 if ( pState->Cpu.ModRM.Bits.Mod != 0132 && pState->Cpu.SIB.Bits.Base == 5133 && pState->Cpu.SIB.Bits.Scale == 0)134 return true;135 }136 137 /*138 * Seems to be an instruction alias here, but I cannot find any docs on it... hrmpf!139 */140 if ( pState->Cpu.pCurInstr->opcode == OP_SHL141 && pState->Cpu.ModRM.Bits.Reg == 6)142 return true;143 144 /*145 * Check for multiple prefixes of the same kind.146 */147 uint32_t fPrefixes = 0;148 for (uint8_t const *pu8 = pState->pbInstr;; pu8++)149 {150 uint32_t f;151 switch (*pu8)152 {153 case 0xf0:154 f = PREFIX_LOCK;155 break;156 157 case 0xf2:158 case 0xf3:159 f = PREFIX_REP; /* yes, both */160 break;161 162 case 0x2e:163 case 0x3e:164 case 0x26:165 case 0x36:166 case 0x64:167 case 0x65:168 f = PREFIX_SEG;169 break;170 171 case 0x66:172 f = PREFIX_OPSIZE;173 break;174 175 case 0x67:176 f = PREFIX_ADDRSIZE;177 break;178 179 case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:180 case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:181 f = pState->Cpu.mode == CPUMODE_64BIT ? PREFIX_REX : 0;182 break;183 184 default:185 f = 0;186 break;187 }188 if (!f)189 break; /* done */190 if (fPrefixes & f)191 return true;192 fPrefixes |= f;193 }194 195 /* segment overrides are fun */196 if (fPrefixes & PREFIX_SEG)197 {198 /* no effective address which it may apply to. */199 Assert((pState->Cpu.prefix & PREFIX_SEG) || pState->Cpu.mode == CPUMODE_64BIT);200 if ( !DIS_IS_EFFECTIVE_ADDR(pState->Cpu.param1.flags)201 && !DIS_IS_EFFECTIVE_ADDR(pState->Cpu.param2.flags)202 && !DIS_IS_EFFECTIVE_ADDR(pState->Cpu.param3.flags))203 return true;204 }205 206 /* fixed register + addr override doesn't go down all that well. */207 if (fPrefixes & PREFIX_ADDRSIZE)208 {209 Assert(pState->Cpu.prefix & PREFIX_ADDRSIZE);210 if ( pState->Cpu.pCurInstr->param3 == OP_PARM_NONE211 && pState->Cpu.pCurInstr->param2 == OP_PARM_NONE212 && ( pState->Cpu.pCurInstr->param1 >= OP_PARM_REG_GEN32_START213 && pState->Cpu.pCurInstr->param1 <= OP_PARM_REG_GEN32_END))214 return true;215 }216 217 /* Almost all prefixes are bad. */218 if (fPrefixes)219 {220 switch (pState->Cpu.pCurInstr->opcode)221 {222 /* nop w/ prefix(es). */223 case OP_NOP:224 return true;225 226 case OP_JMP:227 if ( pState->Cpu.pCurInstr->param1 != OP_PARM_Jb228 && pState->Cpu.pCurInstr->param1 != OP_PARM_Jv)229 break;230 /* fall thru */231 case OP_JO:232 case OP_JNO:233 case OP_JC:234 case OP_JNC:235 case OP_JE:236 case OP_JNE:237 case OP_JBE:238 case OP_JNBE:239 case OP_JS:240 case OP_JNS:241 case OP_JP:242 case OP_JNP:243 case OP_JL:244 case OP_JNL:245 case OP_JLE:246 case OP_JNLE:247 /** @todo branch hinting 0x2e/0x3e... */248 return true;249 }250 251 }252 253 /* All but the segment prefix is bad news. */254 if (fPrefixes & ~PREFIX_SEG)255 {256 switch (pState->Cpu.pCurInstr->opcode)257 {258 case OP_POP:259 case OP_PUSH:260 if ( pState->Cpu.pCurInstr->param1 >= OP_PARM_REG_SEG_START261 && pState->Cpu.pCurInstr->param1 <= OP_PARM_REG_SEG_END)262 return true;263 if ( (fPrefixes & ~PREFIX_OPSIZE)264 && pState->Cpu.pCurInstr->param1 >= OP_PARM_REG_GEN32_START265 && pState->Cpu.pCurInstr->param1 <= OP_PARM_REG_GEN32_END)266 return true;267 break;268 269 case OP_POPA:270 case OP_POPF:271 case OP_PUSHA:272 case OP_PUSHF:273 if (fPrefixes & ~PREFIX_OPSIZE)274 return true;275 break;276 }277 }278 279 /* Implicit 8-bit register instructions doesn't mix with operand size. */280 if ( (fPrefixes & PREFIX_OPSIZE)281 && ( ( pState->Cpu.pCurInstr->param1 == OP_PARM_Gb /* r8 */282 && pState->Cpu.pCurInstr->param2 == OP_PARM_Eb /* r8/mem8 */)283 || ( pState->Cpu.pCurInstr->param2 == OP_PARM_Gb /* r8 */284 && pState->Cpu.pCurInstr->param1 == OP_PARM_Eb /* r8/mem8 */))285 )286 {287 switch (pState->Cpu.pCurInstr->opcode)288 {289 case OP_ADD:290 case OP_OR:291 case OP_ADC:292 case OP_SBB:293 case OP_AND:294 case OP_SUB:295 case OP_XOR:296 case OP_CMP:297 return true;298 default:299 break;300 }301 }302 303 304 /*305 * Check for the version of xyz reg,reg instruction that the assembler doesn't use.306 *307 * For example:308 * expected: 1aee sbb ch, dh ; SBB r8, r/m8309 * yasm: 18F5 sbb ch, dh ; SBB r/m8, r8310 */311 if (pState->Cpu.ModRM.Bits.Mod == 3 /* reg,reg */)312 {313 switch (pState->Cpu.pCurInstr->opcode)314 {315 case OP_ADD:316 case OP_OR:317 case OP_ADC:318 case OP_SBB:319 case OP_AND:320 case OP_SUB:321 case OP_XOR:322 case OP_CMP:323 if ( ( pState->Cpu.pCurInstr->param1 == OP_PARM_Gb /* r8 */324 && pState->Cpu.pCurInstr->param2 == OP_PARM_Eb /* r8/mem8 */)325 || ( pState->Cpu.pCurInstr->param1 == OP_PARM_Gv /* rX */326 && pState->Cpu.pCurInstr->param2 == OP_PARM_Ev /* rX/memX */))327 return true;328 329 /* 82 (see table A-6). */330 if (pState->Cpu.opcode == 0x82)331 return true;332 break;333 334 /* ff /0, fe /0, ff /1, fe /0 */335 case OP_DEC:336 case OP_INC:337 return true;338 339 case OP_POP:340 case OP_PUSH:341 Assert(pState->Cpu.opcode == 0x8f);342 return true;343 344 default:345 break;346 }347 }348 349 /* shl eax,1 will be assembled to the form without the immediate byte. */350 if ( pState->Cpu.pCurInstr->param2 == OP_PARM_Ib351 && (uint8_t)pState->Cpu.param2.parval == 1)352 {353 switch (pState->Cpu.pCurInstr->opcode)354 {355 case OP_SHL:356 case OP_SHR:357 case OP_SAR:358 case OP_RCL:359 case OP_RCR:360 case OP_ROL:361 case OP_ROR:362 return true;363 }364 }365 366 /* And some more - see table A-6. */367 if (pState->Cpu.opcode == 0x82)368 {369 switch (pState->Cpu.pCurInstr->opcode)370 {371 case OP_ADD:372 case OP_OR:373 case OP_ADC:374 case OP_SBB:375 case OP_AND:376 case OP_SUB:377 case OP_XOR:378 case OP_CMP:379 return true;380 break;381 }382 }383 384 385 /* check for REX.X = 1 without SIB. */386 387 /* Yasm encodes setnbe al with /2 instead of /0 like the AMD manual388 says (intel doesn't appear to care). */389 switch (pState->Cpu.pCurInstr->opcode)390 {391 case OP_SETO:392 case OP_SETNO:393 case OP_SETC:394 case OP_SETNC:395 case OP_SETE:396 case OP_SETNE:397 case OP_SETBE:398 case OP_SETNBE:399 case OP_SETS:400 case OP_SETNS:401 case OP_SETP:402 case OP_SETNP:403 case OP_SETL:404 case OP_SETNL:405 case OP_SETLE:406 case OP_SETNLE:407 AssertMsg(pState->Cpu.opcode >= 0x90 && pState->Cpu.opcode <= 0x9f, ("%#x\n", pState->Cpu.opcode));408 if (pState->Cpu.ModRM.Bits.Reg != 2)409 return true;410 break;411 }412 413 /*414 * The MOVZX reg32,mem16 instruction without an operand size prefix415 * doesn't quite make sense...416 */417 if ( pState->Cpu.pCurInstr->opcode == OP_MOVZX418 && pState->Cpu.opcode == 0xB7419 && (pState->Cpu.mode == CPUMODE_16BIT) != !!(fPrefixes & PREFIX_OPSIZE))420 return true;421 422 return false;423 }424 425 426 /**427 110 * Masm style. 428 111 * … … 689 372 /* Use db for odd encodings that we can't make the assembler use. */ 690 373 if ( State.enmUndefOp == kUndefOp_DefineByte 691 && MyDisasYasmFormatterIsOddEncoding(&State))374 && DISFormatYasmIsOddEncoding(&State.Cpu)) 692 375 { 693 376 RTPrintf(" db");
Note:
See TracChangeset
for help on using the changeset viewer.