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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.