- Candy for giving me the notes (And for reading those x86 docs for me ;P)
- froggey for the inline asm basics
- geist for the patience (Went insanse 2 days into the project...) =P
It all started with a hex editor, a list of assembly instructions, and NASM. I began to question how different was 16-bit code to 32-bit code. After doing some examples, I started to notice patterns, and one of them is the usage of the 0x66 prefix. I was hesitant at first to actually write a 16-to-32 bit converter. What got me started were rumors of 64-bit CPUs having no or a buggy VM86 mode. Then, I had a talk with Candy on IRC and thanks to his encouragements, I finally began writing the converter.
The theory
The theory is that Intel kept the opcodes the same between 16 and 32 bit modes. The only difference is, if an opcode has a 0x66 before it, IN 16 BIT MODE it means that the registers for the current opcodes are 32 bits. If an opcode IN 32 BIT MODE has a 0x66 in front of it, this means to use 16 bit register sizes.
And the whole idea is to keep doing this based on the instruction types. Some instructions will need to be emulated (like ones that use the segment registers) or deal with memory offsets (memory offsets rely on the DS segment register). And one common argument is that this is slow. It's not slow because 16 bit programs were made to be slow (As Candy said). Another argument is that this is nuts due to all the X86 opcodes. In reality, the major portion of X86 opcodes are the MMX and SSE add-on opcodes which the BIOS interrupts don't use.
Also, one does not completely emulate each instruction. Out of all the 256 opcodes, I'll probably end up emulating only 15 of them. All I do is apply certain prefixes to the opcode and store it in a buffer, then on every loop cycle I execute the buffer.
And for those that haven't noticed, VMWare uses translating instead of emulating. This is why it's so fast compared to Boch's.
The actual translator
So far, I'm able to run a Hello World example written in 16 bit.
I've been working on adding more instructions to be hopefully execute an interrupt. (So far so good).
Here is a picture of it executing an interrupt:
Here is a picture of how SIMPLE the source is: (Notice that all that's needed to be done for most of the opcodes is for them to be "reformatted" which takes a nanosecond)
Purpose
Well, the whole basic purpose of this is to get this thing to work.
But I would also like to hear opinions or comments on how this may have changed your opinions on things.
Thank you and you have been a great audience.
Best of luck to yah geist!