On Wed, 23 Jan 2002, Nog wrote:
Just for the fun of it I tried to run the dos installer of Mechwarrior 2: Mercenaries. It didn't get too far as the installer crashed on an unhandeled Privileged instruction. According to winedbg the instruction is 0x0002:0x10000 push %cs. To see what the opcode of this instruction might be, I added a trace to the INSTR_EmulateInstruction. Looking at the trace I found that the instruction it was having to emulate was 0x00 which looks very wrong to me.
Yes... 0x00 is an "add" opcode, not a push.
But just to check I simply made that function return true if the instruction was 0x00 but this only seemed to make things worse, the exception still occured but the debugger didn't launch. What I would like to know is, is push %cs realy a Privileged instruction (which I think it might be)?
No, it isn't (unless the stack segment is invalid or something).
Looking into why INSTR_EmulateInstruction doesn't get the right pointer, the offset looked too big to me. Shouldn't it roll over to the next segment after 0xffff?
In 16-bit mode, no, the address should roll back to the beginning of the segment... and this is taken care of in INSTR_EmulateInstruction (which I consider to be a bug for 32-bit DPMI segments)
The problem with the way that it is now is that the following macro, which converts the segment offset pair to linear addresses cuts off the upper bits, which looks correct.
#define PTR_REAL_TO_LIN(seg,off) \ ((void*)(((unsigned int)(seg) << 4) + LOWORD(off)))
What I want to know is why the offset is so high?
The offset can be high if the app uses DPMI to create a 32-bit code segment, but if I remember right, DPMI is currently disabled for DOS apps. But don't worry too much about that offset, because that segment also looks wrong (0x0002 is invalid in protected mode, and in real mode it points to BIOS areas and interrupt tables, no code can live there).