VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

I notice that when executing the instruction "XOR AX,AX" where AX=0x0040 and FLAGS=0xF002, the result is AX=0 and flags=0xF002. In my emulator i'm getting FLAGS=0xF046 as a result (the Zero flag and Parity flag are set, since AX=0(Zero flag) and parity of 0 is even (no set bits in AL)). Anyone knows why Bochs doesn't set the zero and parity flags after an XOR instruction? (Instruction 0x33C0 in my testing (Generic Turbo XT) BIOS)

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 2 of 10, by superfury

User metadata
Rank l33t++
Rank
l33t++

I'm making a simple dump of register state before every instruction is executed in Bochs (before opcodes are executed and when an IRQ or Trap is fired):

typedef struct
{
word CS, SS, DS, ES; //16-bit segment registers!
word AX, BX, CX, DX; //16-bit GP registers!
word SI, DI, SP, BP;
word IP;
word FLAGS;
word type; //Special type indication!
} VERIFICATIONDATA;

My emulator (x86EMU) compares register states before any instruction is executed. At the point of going to execute a XOR AX,AX instruction the flags register is cleared. When executed my emulator sets the Zero flag (AX=0) and Parity flag (AX=0=Parity becomes 1). The dump from bochs points to the correct instruction after the XOR AX,AX instruction and the Zero flag and Parity flags are cleared in the dump.

I'm looking at the Bochs source code... I can't seem to find the Zero and Parity flags being updated after an XOR instruction?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 4 of 10, by peterferrie

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

I'm looking at the Bochs source code... I can't seem to find the Zero and Parity flags being updated after an XOR instruction?

Ah, as Harekiet wrote, they are evaluated in a lazy fashion, meaning that the results are not calculated until they are needed.
For that reason, you won't get a 1:1 match in the flags at the moment where you are comparing right now.
You need to either trace until after an instruction that makes use of the flags in any way, in order to see the result, or ignore the flags completely. To really see the flags, for example:
xor eax, eax
je somewhere
The branch will trigger the evaluation, and you will see a match in the flags values.

Reply 5 of 10, by superfury

User metadata
Rank l33t++
Rank
l33t++

Is there an easy way to disable the lazy flag behaviour using Bochs defines? I need to have correct values to verify my instruction emulation in my emulator.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 7 of 10, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've added the flags by ANDING the dumped resisters and OR it with the getB_*F() result:

		  data.REGFLAGS = ((BX_CPU_THIS_PTR eflags)&0xFFFF)&(~0x8D5); //Create the flags without lazy flags!
data.REGFLAGS |= getB_CF();
data.REGFLAGS |= (getB_PF() << 2);
data.REGFLAGS |= (getB_AF() << 4);
data.REGFLAGS |= (getB_ZF() << 6);
data.REGFLAGS |= (getB_SF() << 7);
data.REGFLAGS |= (getB_OF() << 11); //Apply all lazy flags to our output!

Now the flags work correctly, but once it starts on the first REP STOSW instruction, it seems to go 3 times as slow as my own emulation (one REP STOSW per dump entry). Bochs dumps three times the same dump entry during this instruction? Anyone knows why?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 9 of 10, by superfury

User metadata
Rank l33t++
Rank
l33t++

Is there a simple way to fix this? I need a normal dump for comparing it to my emulator (one dump per STOSW instruction executed).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io