Question

I am writing a second stage bootloader, a part of whose responsibility will be to enter 32 bit protected mode from 16 bit real mode.

My code has some initializing real mode code, a few real mode functions, protected mode code and a few protected mode ones. Here's what I had done (the actual code is in the same order):

  • Added BITS 16 before the starting of first real mode function.

  • Added BITS 32 before the first protected mode function

  • Added BITS 16 before the initializing real mode code

  • Added BITS 32 before the initializing protected mode code (basically before mov cr0, eax after ORing eax with 1.

This didn't work, so I read NASM's manual which said its not necessary to use this directive. I removed all of them and the code worked!

So what was the mistake in my approach ? Also, am I somehow mixing up bitness and the processor mode ?

Was it helpful?

Solution

BITS 32 would go after mov cr0, as that is still executed in real mode. You shouldn't switch to BITS 32 until you do the JMP 0x08:ProtectedModeMain instruction,

OTHER TIPS

You do need the bits directives, pretty much as you showed except for the last point: the cpu is still executing 16 bit code at that time, until you reload CS (by a far jump, usually).

The 16 bit part of the code might accidentally work when assembled as 32 bit if you are lucky, depending on the instructions used.

I am pretty sure if the NASM manual mentions you don't need this directive, it is talking about code which uses the same "bitness" throughout, and one that has been specified on the command line (or selected by the format).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top