VOGONS


First post, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I was debugging a program and ran into an instruction that disassembles as "movsx eax,ax", but "movsx eax,al" is executed; which had me thinking there was a CPU bug for a moment. The opcode is 0F BE C0 with a disassembly template of "movsx %Gv,%Eb". The second operand is byte size in the template, so a 16-bit register there is a disassembly bug.

static void reg_name(int regnum, char size)
{
if (size == 'F') { /* floating point register? */
uprintf("st(%d)", regnum);
return;
}
if ((((size == 'c') || (size == 'v')) && (opsize == 32)) || (size == 'd'))
uputchar('e');
- if ((size=='q' || size == 'b' || size=='c') && !wordop) {
+ if (size == 'b' || ((size=='q' || size=='c') && !wordop)) {
uputchar("acdbacdb"[regnum]);
uputchar("llllhhhh"[regnum]);
} else {
uputchar("acdbsbsd"[regnum]);
uputchar("xxxxppii"[regnum]);
}
}

It seems the wordop var is not applicable to %E operands, so the above change just trusts a byte size in the template regardless of the value of wordop. There are certainly other ways to correct the problem, but this way is fairly direct.

Reply 1 of 1, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Looked at why wordop==true for some (not all) instructions with byte operands, and found what appears to be the source of the problem. Bit 0 of the first opcode byte usually denotes byte or word, but prefix 0x0f instructions should look at the byte after the prefix byte. I think this patch against current source does a better job of targetting the problem than what I previously suggested.