Now, 0SOS can execute the 32-bit code as well.

That mean, We can use 32bit general registers.

Like eax, esi registers.

I’m so glad.

Look at this:


As you can see, It is completely working.

If you say like this: “I can simply do it, using C Language”

Please, Close this post.

Anyway, I’ve made an effort for understanding.

And success!


Especially, segment table, the range of used memory and stack makes me a headache.

First of all, Following steps are the description for change 16-bit real-mode to 32-bit protect-mode:

First, Organize a GDT table, and then addressing GDT to the processor.

That table’s first elements is NULLDescriptor that is filled 0 in Descriptor element.

Second, We need to define descriptor. Me and author insert Code and Data segment descriptor in GDT.

This step makes me much harder to understand.

I guess code and data descriptor shouldn’t overlap. Something weird is the base address of descriptor and access limitation are the same.

But I just miss understanding.


Eventually, on the current code, specifically on the defined table, segment descriptors doesn’t sperate the code and data area of the memory.

Both of them could address the 0~4GB memory area.

Also, the stack couldn’t be overlapped because stack grows downwards from the top.

(Because that have a 64kb limit. You should see esp and ebp in the code)

So We can find an expression of calculation for a relative address on the example code.

Like (LABEL - $$ + 0x10000).

Anyway, I understand completely.

And then, Third, Set up CR0 Register that manages operating mode.

You can see the table of the setup value below.

And If you want to find more, google it.

After then, You just jump to the 32-bit code area.


Anyway below code is the entry point of my kernel for the 32-bit system:

[ORG 0x00]
[BITS 16]


    mov ax, 0x1000

    mov ds, ax
    mov es, ax
    cli        ;Ignore Interrupt


    ;    Now Switch Protected Mode.
    ;   CR0 Register
    ;    Summary: 
    ;        Disable Paging, Disable Cache, Internal FPU, Disable Align Check
    ;   fields:
    ;    |PG|CD|NW|  |  |  |  |  |  |  |  |  |  |AM|  |WP|
    ;    31---------------------------------------------16
    ;    | 0| 1| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0|
    ;    |  |  |  |  |  |  |  |  |  |  |NE|ET|TS|EM|MP|PE| 
    ;    15----------------------------------------------0
    ;    | 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 1| 1| 1| 0| 1| 1|
    ;    0b01000000000000000000000000111011    
    ;     0x4000003B

    mov eax, 0x4000003B
    mov cr0, eax

    jmp dword 0x08 : (PROTECTEDMODE - $$ + 0x10000)

    ; Following Code Now Protected Mode

[BITS 32]

    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    mov ss, ax
    mov esp, 0XFFFE
    mov ebp, 0XFFFE
    push (SWITCHMESSAGE - $$ + 0x10000)
    push 2
    push 0
    call PRINT
    add  esp, 12

    jmp $

    push ebp
    mov ebp, esp
    push esi
    push edi
    push eax
    push ecx
    push edx

    mov eax, dword [ebp + 12]
    mov esi, 160
    mul esi
    mov edi, eax
    mov eax, dword[ebp + 8]
    mov esi, 2
    mul esi
    add edi, eax
    mov esi, dword[ebp + 16]
    mov cl, byte[esi]
    cmp cl,0
    mov byte[edi + 0xB8000], cl
    add esi,1
    add edi,2    
    jmp .PRINTLOOP
    pop edx
    pop ecx
    pop eax
    pop edi
    pop esi
    pop ebp


align 8, db 0

dw 0x0000    ;For Align

    dw GDTREND - GDT -1
    dd GDT - $$ + 0x10000

    dw 0x0000
    dw 0x0000
    db 0x00
    db 0x00
    db 0x00
    db 0x00

    dw 0xFFFF    ; Limit[15:0]
    dw 0x0000    ; Base[15:0]
    db 0x00        ; Base[23:16]
    db 0x9A        ; P = 1, DPL = 0, Code Segment, Execute/Read
    db 0xCF        ; G = 1, D = 1, L = 0, Limit [19:16]
    db 0x00        ; Base[31:24]
    dw 0xFFFF    ; Limit
    dw 0x0000    ; Base
    db 0x00        ; Base
    db 0x92        ; P=1, DPL =0, Data Segment, Read/Write
    db 0xCF        ; G= 1, D= 1, L= 0, Limit
    db 0x00        ; Base

SWITCHMESSAGE: db 'Switch Success. Now Running 32bit Protected Mode.',0

times 512 - ( $ - $$) db 0x00

It won’t hard code to understand. Also, we should change the sector number to 1 for the bootloader.

Surely, real-mode and protected-mode are different for addressing memory.

Well, Well, I’m excited about how much complex on IA-32e mode.

And currently, paging is disabled but if it is enabled…

Anyway, I’ve made a table of the code.

On the vim:


I’m not sure above table correct.

well, Worke is done for 32bit! Let’s write kernel code.