Page 1 of 1

Working with Real Mode IVT to work on a 8086 Emulator

Posted: Fri Dec 06, 2013 10:18 pm
by PearOs
Hey guys! So I have been working on my 8086 emulator in my operating system finally! Now that I have enough done where I can do so. But I've run into a slight problem. I read the 0x10 Entry in the IVT like this:

Code: Select all

short segment = Memory.Get_16(0x0040);
short offset = Memory.Get_16(0x0040 + 2);
That code above looks right. According to the wiki Interrupt_Vector_Table
Then I tried to convert the segment and offset to a actual Memory address like this:

Code: Select all

INT10Pointer = (uint)((segment * 0x10) + offset);
Which according to this wikie Segmentation thats right. But when I run my Os, I get a physical address of 35745760 which is the 35mb mark and My os doesn't even reach that at the moment. None of my code overwrites the IVT but I wonder if my boot loader might. Hard to say but are my equations right?

Thanks, Matt

Re: Working with Real Mode IVT to work on a 8086 Emulator

Posted: Fri Dec 06, 2013 10:44 pm
by PearOs
Ok so I found a bug in my Memory_Get_16 code and fixed that. But then I found a bug within my Segment converter code so the new is:

Code: Select all

short offset = Memory.Get_16(0x0040);
short segment = Memory.Get_16(0x0040 + 2);
INT10Pointer = (uint)((segment * 0x10) + offset);
Which I think is right, and my Os outputs 789246 as the pointer to where INT 10h starts in Memory. So I think that is right.

Re: Working with Real Mode IVT to work on a 8086 Emulator

Posted: Fri Dec 06, 2013 10:48 pm
by b.zaar
PearOs wrote:

Code: Select all

short segment = Memory.Get_16(0x0040);
short offset = Memory.Get_16(0x0040 + 2);
These are the wrong way round.
PearOs wrote:

Code: Select all

INT10Pointer = (uint)((segment * 0x10) + offset);
And these should be uint16_t before the addition, the max value should be 0xFFFFF = 1048575

Re: Working with Real Mode IVT to work on a 8086 Emulator

Posted: Sat Dec 07, 2013 3:50 am
by PearOs
Ok I see. Well I think I have it right now. Because the offset is first which is 2 bytes then follows the segment which is 2 bytes. Though I have found a very strange bug and I am wondering what you guys think. I have been testing my os's ability
to decompile real mode instructions for the int 10h call. I found a weird one.

lock mov al, byte[si + 61440] which I think is correct.

But when I use nasm disam for the same bytes I get

lock mov al,[si-0x1000] and 0x1000 is (61440) so thats good but why is it minus now? Cause if I write that
instruction in Nasm and decompile it, it will say that "+ 61440" is "- 61440" when thats not what I typed. But if I do "- 61440" I get "+ 61440" from Nasm Dism, did I just find a bug?

Thanks,

Matt

Re: Working with Real Mode IVT to work on a 8086 Emulator

Posted: Sat Dec 07, 2013 4:10 am
by Combuster
PearOs wrote:lock mov al, byte[si + 61440] which I think is correct.
LOCK makes read-modify-write operations atomic across the bus. This is simply a read, and therefore LOCK is invalid.

Re: Working with Real Mode IVT to work on a 8086 Emulator

Posted: Sat Dec 07, 2013 6:00 am
by Brendan
Hi,
PearOs wrote:lock mov al,[si-0x1000] and 0x1000 is (61440) so thats good but why is it minus now? Cause if I write that
instruction in Nasm and decompile it, it will say that "+ 61440" is "- 61440" when thats not what I typed. But if I do "- 61440" I get "+ 61440" from Nasm Dism, did I just find a bug?
Note that -4096 (as a signed 16-bit number) is the exact same pattern of bits as 61440 (as an unsigned 16-bit number).

I'm not sure if this is a bug or correct behaviour.

If you assume that the displacement is a signed 16-bit value, then it'd only be capable of storing values from -32768 to +32767 and "[si+61440]" should be treated as a programming error (number too large for signed 16-bit).

If you assume that the displacement is an unsigned 16-bit value (where the CPU ignores overflow and essentially does "offset = (si + unsigned_displacement) & 0xFFFF") then it's not a bug at all.

If you assume that either case is equally valid (e.g. the programmer is free to treat the displacement as signed or unsigned), then that means valid values for the displacement would range from -32768 to 65535.

I tested NASM, and it does accept any value from -32768 to 65536 (inclusive), and gives a "data exceeds bounds" warning for anything outside that range. I don't know why 65536 is allowed (it doesn't fit in any signed or unsigned 16-bit integer).

For debuggers, it's impossible to guess what the original programmer's intent was, and a debugger can't know if it should display "-0x1000" or "+0xF000". Any debugger that displays "-0xF000" is buggy, but I tested ndisasm and it doesn't do that (it displays "-0x1000").


Cheers,

Brendan

Re: Working with Real Mode IVT to work on a 8086 Emulator

Posted: Sat Dec 07, 2013 12:13 pm
by PearOs
Brendan wrote:Hi,
PearOs wrote:lock mov al,[si-0x1000] and 0x1000 is (61440) so thats good but why is it minus now? Cause if I write that
instruction in Nasm and decompile it, it will say that "+ 61440" is "- 61440" when thats not what I typed. But if I do "- 61440" I get "+ 61440" from Nasm Dism, did I just find a bug?
Note that -4096 (as a signed 16-bit number) is the exact same pattern of bits as 61440 (as an unsigned 16-bit number).

I'm not sure if this is a bug or correct behaviour.

If you assume that the displacement is a signed 16-bit value, then it'd only be capable of storing values from -32768 to +32767 and "[si+61440]" should be treated as a programming error (number too large for signed 16-bit).

If you assume that the displacement is an unsigned 16-bit value (where the CPU ignores overflow and essentially does "offset = (si + unsigned_displacement) & 0xFFFF") then it's not a bug at all.

If you assume that either case is equally valid (e.g. the programmer is free to treat the displacement as signed or unsigned), then that means valid values for the displacement would range from -32768 to 65535.

I tested NASM, and it does accept any value from -32768 to 65536 (inclusive), and gives a "data exceeds bounds" warning for anything outside that range. I don't know why 65536 is allowed (it doesn't fit in any signed or unsigned 16-bit integer).

For debuggers, it's impossible to guess what the original programmer's intent was, and a debugger can't know if it should display "-0x1000" or "+0xF000". Any debugger that displays "-0xF000" is buggy, but I tested ndisasm and it doesn't do that (it displays "-0x1000").


Cheers,

Brendan
Ok thanks Brendan! It might be that I am actually not reading back the INT10h code I think because when I look at the opcodes my decompiler is printing out, they don't logically make any sense. I'll attach a pic, also is there anyway I could in Bochs or some other Virtual Machine see what the INT10h code is that they are running? Like I know they load a VESA and VGA Bios so it would be nice to see the original code and then make sure my OS is reading it back properly if you get what I'm saying.

Anyways, here's a few opcodes I'm getting from where INT10h is supposed to be in RAM.

Re: Working with Real Mode IVT to work on a 8086 Emulator

Posted: Sat Dec 07, 2013 1:58 pm
by PearOs
So I did some testing on my own and in Bochs I'm getting the exact same instructions that I got in VMWare which leads me to assume I must be overwriting the code somehow. So I the physical address of INT10h and Bochs and found it to be 786762 which is the same one my OS prints out when it runs, which means I'm not overwriting the IVT.

I set a physical address break point in Bochs in real mode and called 786762 and saw the first instruction to be: Pushf which that actually makes some sense. I am using ISOLinux to boot my os but is that somehow overwriting the BIOS code? Cause My code in my OS doesn't.. Thanks a ton.

- Matt

Re: Working with Real Mode IVT to work on a 8086 Emulator

Posted: Sat Dec 07, 2013 2:09 pm
by PearOs
Nevermind! I got it! Silly me. I forgot to set my pointer address in my Opcode reader stream. Lol so I was reading code from 0x0. It's working perfectly now. Thanks anyways guys. Ill post back again if I have any further issues. :lol: