freecrac wrote:Hello.
Like "h0bby1" said for to switch between the 16 bit realmode and the 32 bit protected mode we need at last a "far jmp" to the codesegment and the changing will first have an effect after this far jmp of which 32 bit attribute correspond to the {bits} directive of the section the code is in.
[bits32]
For to get the 32 bit addressmode we need additional to set the Default-Size-Bit in the codesegmet descriptor before. And if this D-bit is set, then the default size of all operands and addresses of the instructions in this 32 bit-codesegment is 32 bit without to use operand-size and/or address-size prefixes. But if we want to use 16 bit operands and/or 16 bit addresses within the 32 bit mode, then we need one or both of these size-prefixes for each one of this 16 bit instruction for to reverse the default operand- and address-size in the 32 bit codesegment.
[bits16]
If the D-bit is not set, then we get the 16 bit addressmode and all operands and addresses of the instructions in this 16 bit-codesegment is 16 bit without to use operand-size and/or address-size prefixes. If we want to use 32 bit operands and/or 32 bit addresses(80386+) within the 16 bit mode, then we need one or both of these size-prefixes for each of this 32 bit instruction for to reverse the default operand- and address-size in the 16 bit codesegment.
Dirk
it's not only this, but also call and interupt instruction are not the same, as the return address is 16 bit, the stack and iret/ret instruction is different
you can do most of the 32 bit instruction in 16 bit mode, but the opcode will be different, and some opcode have different effect in 16 bit and 32 bit mode like call/int/ret/iret, if you want to make a far call to a 16 bit routine from a 32 bit code segment, need to be careful about how the calls are made, because the call in the 32 bit codesegment will push the return address as 32 bit, but the ret instruction in the 16 bit codesegment will only pop 16 bit return address, same for interupt handling
if you just want to switch from real mode to 32 bit protected, there is two different things that need to be done, first switch the cpu to protected mode which will most change how address and segment register are handled, and then switching to a 32 bit code segment to activate the 32 bit mode of the cpu, when you are in real mode, and just enable protected mode, the cpu is still in 16 bit mode with protected mode memory
so you need to first create a 32 bit code segment in the gdt, then load the 32 bit code in it, or make the segment base at the begining of physical memory, and then switch the cpu to protected mode, and make a far jump to the start address inside of the code segment, with something like jmp 0x08:start_addr, 0x08 is the selector id for the 32 bit code segment, and start_addr the address of the entry point of the 32 bit code relative to the start of the segment