Re: x86emu emulation problem
Tim Roberts <[email protected]>
| Newsgroups | gmane.comp.xfree86.devel |
|---|---|
| Organization | Providenza & Boekelheide, Inc. |
| Message-ID | <[email protected]> |
jf simon wrote:
> Hi,
>
>>> 2- The same code as seen from ndisasm:
>>>
>>> 000068DA A00080 mov al,[0x8000]
>>> 000068DD 04F5 add al,0xf5
>>> 000068DF 0002 add [bp+si],al
>>> 000068E1 C8008015 enter 0x8000,0x15
>>> 000068E5 0E push cs
>>> 000068E6 0106C800 add [0xc8],ax
>>> 000068EA 80100E adc byte [bx+si],0xe
>>> 000068ED 0105 add [di],ax
>>> 000068EF C800800B enter 0x8000,0xb
>>> 000068F3 0E push cs
>>> 000068F4 0104 add [si],ax
>>> 000068F6 C8008006 enter 0x8000,0x6
>>> 000068FA 0E push cs
>>> 000068FB 0102 add [bp+si],ax
>>> 000068FD E80080 call 0xe900 <<<<<!!!HERE AGAIN
>>>
>>
>>
>>
>> This is probably data -- either font data or VGA register tables. Can
>> you trace backwards any more and figure out how you got to 68DA?
>>
>>
>>
> You are right. I have found that the problem was on a JMP SHORT which
> was incorrectly landing in that part of the VGA BIOS. The relative
> displacement was negative (was 0xBA), but the JMP was considering it
> to be a jump to [PC]+0xBA rather than applying the signed arithmetic.
> Setting GCC "-fsigned-char " switch made the signed displacemnt
> correctly applied....and solved the problem. I didn't know that the
> "char" type was unsigned by default.
>
> On a different issue, I think that the emulator may be wrong as it
> sometimes fetches values from the DATA segment, even if the CS was
> previously selected as the source segment. For exemple, in
> x86emu/ops.c, see [*]:
>
>
> if (M.x86.mode & SYSMODE_PREFIX_DATA) {
> u32 destval,srcval;
>
> DECODE_PRINTF("TEST\tDWORD PTR ");
> destoffset = decode_rm00_address(rl);
> DECODE_PRINTF(",");
> srcval = fetch_long_imm();
> DECODE_PRINTF2("%x\n", srcval);
> destval = fetch_data_long(destoffset);
> TRACE_AND_STEP();
> test_long(destval, srcval);
> } else {
> u16 destval,srcval;
> DECODE_PRINTF("TEST\tWORD PTR ");
> destoffset = decode_rm00_address(rl);
> DECODE_PRINTF(",");
> srcval = fetch_word_imm();
> DECODE_PRINTF2("%x\n", srcval);
> destval = fetch_data_word(destoffset); [*]
> TRACE_AND_STEP();
> test_word(destval, srcval);
> }
>
> [*] : shouldn't that be a fetch from the CS segt, since the mode (in
> M.x86.mode) is not of the DATA type?
No. When they say SYSMODE_PREFIX_DATA, they are talking about the 0x66
prefix, which Intel calls the "operand size override". That determines
whether the instruction uses 16-bit units or 32-bit units. Compare with
SYSMODE_PREFIX_ADDR, the 0x67 prefix, which Intel calls "address size
override", which determines whether the addresses are 16-bit or 32-bits
wide.
The fetch_data_long and fetch_data_word functions will use the segment
overrides to decide which segment register to use.
--
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.