📄 entry.asm
字号:
[BITS 32]
%include 'c32.mac'
;-----------------------------------------------------------------------------;
; Macros (to use 32-bit instructions while in real mode) ;
;-----------------------------------------------------------------------------;
%macro LGDT32 1
DB 66h ; 32-bit operand override
DB 8Dh ; lea (e)bx,Addr
DB 1Eh
DD %1
DB 0Fh ; lgdt fword ptr [bx]
DB 01h
DB 17h
%endmacro
%macro LIDT32 1
DB 66h ; 32-bit operand override
DB 8Dh ; lea (e)bx,Addr
DB 1Eh
DD %1
DB 0Fh ; lidt fword ptr [bx]
DB 01h
DB 1Fh
%endmacro
%macro FJMP32 2
DB 66h ; 32-bit operand override
DB 0EAh ; far jump
DD %2 ; 32-bit offset
DW %1 ; 16-bit selector
%endmacro
extern main
global EntryPoint, Idt, Gdt
; ORG 0x100
;-----------------------------------------------------------------------------;
; Entry Point. The CPU is executing in 16-bit real mode. ;
;-----------------------------------------------------------------------------;
proc EntryPoint
LGDT32 GdtDesc ; Load GDT descriptor
LIDT32 IdtDesc ; Load IDT descriptor
mov eax,cr0 ; Get control register 0
or ax,1 ; Set PE bit (bit #0) in (e)ax
mov cr0,eax ; Activate protected mode!
jmp $+2 ; To flush the instruction queue.
; The CPU is now executing in 16-bit protected mode. Make a far jump in order to
; load CS with a selector to a 32-bit executable code descriptor.
FJMP32 08h, EntryPoint32 ; Jump to EntryPoint32
; This point is never reached.
endproc
;-----------------------------------------------------------------------------;
; The CPU is now executing in 32-bit protected mode. ;
;-----------------------------------------------------------------------------;
proc EntryPoint32
; Initialize all segment registers to 10h (entry #2 in the GDT)
mov ax,10h ; entry #2 in GDT
mov ds,ax ; ds = 10h
mov es,ax ; es = 10h
mov fs,ax ; fs = 10h
mov gs,ax ; gs = 10h
mov ss,ax ; ss = 10h
; Set the top of stack to allow stack operations.
mov esp,8000h ; arbitrary top of stack
; Call main(), which is not expected to return.
call main
; In case main() returns, enter an infinite loop.
IdleLoop:
hlt
jmp IdleLoop
; This point is never reached.
endproc
;-------------------------------------------------------------------------------;
; Tables Descriptors (to use with LGDT32 & LIDT32) ;
;-------------------------------------------------------------------------------;
ALIGN 4
GdtDesc: ; GDT descriptor
DW GDT_SIZE - 1 ; GDT limit
DD Gdt ; GDT base address (below)
ALIGN 4
IdtDesc: ; IDT descriptor
DW IDT_SIZE - 1 ; IDT limit
DD Idt ; IDT base address (below)
;-------------------------------------------------------------------------------;
; GDT ;
;-------------------------------------------------------------------------------;
ALIGN 4
; Global Descriptor Table (GDT)
Gdt:
; GDT[0]: Null entry, never used.
DD 0
DD 0
; GDT[1]: Executable, read-only code, base address of 0, limit of FFFFFh,
; granularity bit (G) set (making the limit 4GB)
DW 0FFFFh ; Limit[15..0]
DW 0000h ; Base[15..0]
DB 00h ; Base[23..16]
DB 10011010b ; P(1) DPL(00) S(1) 1 C(0) R(1) A(0)
DB 11001111b ; G(1) D(1) 0 0 Limit[19..16]
DB 00h ; Base[31..24]
; GDT[2]: Writable data segment, covering the save address space than GDT[1].
DW 0FFFFh ; Limit[15..0]
DW 0000h ; Base[15..0]
DB 00h ; Base[23..16]
DB 10010010b ; P(1) DPL(00) S(1) 0 E(0) W(1) A(0)
DB 11001111b ; G(1) B(1) 0 0 Limit[19..16]
DB 00h ; Base[31..24]
GDT_SIZE EQU $ - Gdt ; Size, in bytes
;-------------------------------------------------------------------------------;
; IDT ;
;-------------------------------------------------------------------------------;
; Interrupt Descriptor Table (IDT)
Idt:
times 64 dd 0
times 32 dd 0
times 32 dd 0
IDT_SIZE EQU $ - Idt ; Size, in bytes
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -