%include "pm.inc"
[section .data]
;GDT==================================================================
LABEL_DESC_GDT: Descriptor 0,0,0
LABEL_DESC_FLAT_RW: Descriptor 0,0ffffh,DA_DRW + DA_32 + DA_LIMIT_4K
LABEL_DESC_FLAT_C: Descriptor 0,0ffffh,DA_CR + DA_32 + DA_LIMIT_4K
LABEL_DESC_CODE32: Descriptor 0,Code32_Len - 1,DA_C + DA_32
LABEL_DESC_VIDEO: Descriptor 0b8000h,0ffffh,DA_DRW
Selector_Flat_RW equ LABEL_DESC_FLAT_RW - LABEL_DESC_GDT
Selector_Flat_C equ LABEL_DESC_FLAT_C - LABEL_DESC_GDT
Selector_Code32 equ LABEL_DESC_CODE32 - LABEL_DESC_GDT
Selector_Video equ LABEL_DESC_VIDEO - LABEL_DESC_GDT
Selector_Loader_Flat_RW equ 8
Selector_Loader_Flat_C equ 16
GDT_Len equ $ - LABEL_DESC_GDT
GDT_Ptr: dw GDT_Len - 1
dd 0
;IDT==================================================================
LABEL_GATE_IDT:
LABEL_GATE_DIVIDE_ERROR: Gate Selector_Code32,LABEL_DIVIDE_ERROR,0,DA_386IGate
LABEL_GATE_SINGLE_STEP_EXCEPTION: Gate Selector_Code32,LABEL_SINGLE_STEP_EXCEPTION,0,DA_386IGate
LABEL_GATE_NMI: Gate Selector_Code32,LABEL_NMI,0,DA_386IGate
LABEL_GATE_BREAKPOINT_EXCEPTION: Gate Selector_Code32,LABEL_BREAKPOINT_EXCEPTION,0,DA_386IGate
LABEL_GATE_OVERFLOW: Gate Selector_Code32,LABEL_OVERFLOW,0,DA_386IGate
LABEL_GATE_BOUNDS_CHECK: Gate Selector_Code32,LABEL_BOUNDS_CHECK,0,DA_386IGate
LABEL_GATE_INVILID_OPCODE: Gate Selector_Code32,LABEL_INVILID_OPCODE,0,DA_386IGate
LABEL_GATE_COPR_NOT_AVAILABLE: Gate Selector_Code32,LABEL_COPR_NOT_AVAILABLE,0,DA_386IGate
LABEL_GATE_DOUBLE_FAULT: Gate Selector_Code32,LABEL_DOUBLE_FAULT,0,DA_386IGate
LABEL_GATE_COPR_SEG_OVERRUN: Gate Selector_Code32,LABEL_COPR_SEG_OVERRUN,0,DA_386IGate
LABEL_GATE_INVALID_TSS: Gate Selector_Code32,LABEL_INVALID_TSS,0,DA_386IGate
LABEL_GATE_SEGMENT_NOT_PRESENT: Gate Selector_Code32,LABEL_SEGMENT_NOT_PRESENT,0,DA_386IGate
LABEL_GATE_STACK_EXCEPTION: Gate Selector_Code32,LABEL_STACK_EXCEPTION,0,DA_386IGate
LABEL_GATE_GENERAL_PROTECTION: Gate Selector_Code32,LABEL_GENERAL_PROTECTION,0,DA_386IGate
LABEL_GATE_PAGE_FAULT: Gate Selector_Code32,LABEL_PAGE_FAULT,0,DA_386IGate
LABEL_GATE_DUMMY: Gate 0,0,0,0
LABEL_GATE_COPR_ERROR: Gate Selector_Code32,LABEL_COPR_ERROR,0,DA_386IGate
%rep 15
Gate 0,0,0,0
%endrep
Gate Selector_Code32,LABEL_HWINT00,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT01,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT02,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT03,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT04,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT05,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT06,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT07,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT08,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT09,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT10,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT11,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT12,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT13,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT14,0,DA_386IGate
Gate Selector_Code32,LABEL_HWINT15,0,DA_386IGate
%rep 209
Gate 0,0,0,0
%endrep
IDT_Len equ $ - LABEL_GATE_IDT
IDT_Ptr: dw IDT_Len - 1
dd 0
;some data============================================================
Disp_Pos: dd 0
Return: db 0ah,0
Space: db ' ',0
;stack space==========================================================
[section .bss]
Stack_Space resb 2 * 1024
Top_Of_Stack:
[section .text]
global _start
_start:
mov ax,Selector_Loader_Flat_RW
mov ds,ax
mov es,ax
xor eax,eax
add eax,_start
mov word [LABEL_DESC_CODE32 + 2],ax
shr eax,16
mov byte [LABEL_DESC_CODE32 + 4],al
mov byte [LABEL_DESC_CODE32 + 7],ah
mov eax,LABEL_DESC_GDT
mov dword [GDT_Ptr + 2],eax
lgdt [GDT_Ptr]
mov ax,Selector_Flat_RW
mov ds,ax
mov es,ax
mov ss,ax
mov esp,Top_Of_Stack
mov ax,Selector_Video
mov gs,ax
mov eax,LABEL_GATE_IDT
mov dword [IDT_Ptr + 2],eax
lidt [IDT_Ptr]
call Init_8259A
jmp Selector_Flat_C:LABEL_TEST
LABEL_TEST:
;jmp 80:0
sti
hlt
_LABEL_DIVIDE_ERROR:
LABEL_DIVIDE_ERROR equ _LABEL_DIVIDE_ERROR - $$
push 0ffffffffh
push 0
jmp LABEL_EXCEPTION
_LABEL_SINGLE_STEP_EXCEPTION:
LABEL_SINGLE_STEP_EXCEPTION equ _LABEL_SINGLE_STEP_EXCEPTION - $$
push 0ffffffffh
push 1
jmp LABEL_EXCEPTION
_LABEL_NMI:
LABEL_NMI equ _LABEL_NMI - $$
push 0ffffffffh
push 2
jmp LABEL_EXCEPTION
_LABEL_BREAKPOINT_EXCEPTION:
LABEL_BREAKPOINT_EXCEPTION equ _LABEL_BREAKPOINT_EXCEPTION - $$
push 0ffffffffh
push 3
jmp LABEL_EXCEPTION
_LABEL_OVERFLOW:
LABEL_OVERFLOW equ _LABEL_OVERFLOW - $$
push 0ffffffffh
push 4
jmp LABEL_EXCEPTION
_LABEL_BOUNDS_CHECK:
LABEL_BOUNDS_CHECK equ _LABEL_BOUNDS_CHECK - $$
push 0ffffffffh
push 5
jmp LABEL_EXCEPTION
_LABEL_INVILID_OPCODE:
LABEL_INVILID_OPCODE equ _LABEL_INVILID_OPCODE - $$
push 0ffffffffh
push 6
jmp LABEL_EXCEPTION
_LABEL_COPR_NOT_AVAILABLE:
LABEL_COPR_NOT_AVAILABLE equ _LABEL_COPR_NOT_AVAILABLE - $$
push 0ffffffffh
push 7
jmp LABEL_EXCEPTION
_LABEL_DOUBLE_FAULT:
LABEL_DOUBLE_FAULT equ _LABEL_DOUBLE_FAULT - $$
push 8
jmp LABEL_EXCEPTION
_LABEL_COPR_SEG_OVERRUN:
LABEL_COPR_SEG_OVERRUN equ _LABEL_COPR_SEG_OVERRUN - $$
push 0ffffffffh
push 9
jmp LABEL_EXCEPTION
_LABEL_INVALID_TSS:
LABEL_INVALID_TSS equ _LABEL_INVALID_TSS - $$
push 10
jmp LABEL_EXCEPTION
_LABEL_SEGMENT_NOT_PRESENT:
LABEL_SEGMENT_NOT_PRESENT equ _LABEL_SEGMENT_NOT_PRESENT - $$
push 11
jmp LABEL_EXCEPTION
_LABEL_STACK_EXCEPTION:
LABEL_STACK_EXCEPTION equ _LABEL_STACK_EXCEPTION - $$
push 12
jmp LABEL_EXCEPTION
_LABEL_GENERAL_PROTECTION:
LABEL_GENERAL_PROTECTION equ _LABEL_GENERAL_PROTECTION - $$
push 13
jmp LABEL_EXCEPTION
_LABEL_PAGE_FAULT:
LABEL_PAGE_FAULT equ _LABEL_PAGE_FAULT - $$
push 14
jmp LABEL_EXCEPTION
_LABEL_COPR_ERROR:
LABEL_COPR_ERROR equ _LABEL_COPR_ERROR - $$
push 0ffffffffh
push 16
jmp LABEL_EXCEPTION
LABEL_EXCEPTION:
call Exception_Handler
add esp,8
hlt
_LABEL_HWINT00:
LABEL_HWINT00 equ _LABEL_HWINT00 - $$
push 0
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT01:
LABEL_HWINT01 equ _LABEL_HWINT01 - $$
push 1
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT02:
LABEL_HWINT02 equ _LABEL_HWINT02 - $$
push 2
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT03:
LABEL_HWINT03 equ _LABEL_HWINT03 - $$
push 3
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT04:
LABEL_HWINT04 equ _LABEL_HWINT04 - $$
push 4
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT05:
LABEL_HWINT05 equ _LABEL_HWINT05 - $$
push 5
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT06:
LABEL_HWINT06 equ _LABEL_HWINT06 - $$
push 6
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT07:
LABEL_HWINT07 equ _LABEL_HWINT07 - $$
push 7
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT08:
LABEL_HWINT08 equ _LABEL_HWINT08 - $$
push 8
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT09:
LABEL_HWINT09 equ _LABEL_HWINT09 - $$
push 9
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT10:
LABEL_HWINT10 equ _LABEL_HWINT10 - $$
push 10
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT11:
LABEL_HWINT11 equ _LABEL_HWINT11 - $$
push 11
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT12:
LABEL_HWINT12 equ _LABEL_HWINT12 - $$
push 12
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT13:
LABEL_HWINT13 equ _LABEL_HWINT13 - $$
push 13
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT14:
LABEL_HWINT14 equ _LABEL_HWINT14 - $$
push 14
call Spurious_IRQ
add esp,4
hlt
_LABEL_HWINT15:
LABEL_HWINT15 equ _LABEL_HWINT15 - $$
push 15
call Spurious_IRQ
add esp,4
hlt
;Exception_Handler====================================================
Exception_Handler:
push ebp
mov ebp,esp
push eax
push ecx
mov ecx,5 * 80
mov dword [Disp_Pos],0
.1:
push Space
call Disp_Str
add esp,4
loop .1
mov dword [Disp_Pos],0
mov eax,[ebp + 8]
push eax
call Disp_32Bit_Int
add esp,4
push Return
call Disp_Str
add esp,4
mov eax,[ebp + 12]
push eax
call Disp_32Bit_Int
add esp,4
push Return
call Disp_Str
add esp,4
mov eax,[ebp + 16]
push eax
call Disp_32Bit_Int
add esp,4
push Return
call Disp_Str
add esp,4
mov eax,[ebp + 20]
push eax
call Disp_32Bit_Int
add esp,4
push Return
call Disp_Str
add esp,4
mov eax,[ebp + 24]
push eax
call Disp_32Bit_Int
add esp,4
push Return
call Disp_Str
add esp,4
pop ecx
pop eax
pop ebp
ret
;end of Exception_Handler=============================================
;Spurious_IRQ=========================================================
Spurious_IRQ:
push ebp
mov ebp,esp
push eax
push ecx
mov ecx,5 * 80
mov dword [Disp_Pos],0
.1:
push Space
call Disp_Str
add esp,4
loop .1
mov dword [Disp_Pos],0
mov eax,[ebp + 8]
push eax
call Disp_32Bit_Int
add esp,4
push Return
call Disp_Str
add esp,4
pop ecx
pop eax
pop ebp
ret
;end of Spurious_IRQ==================================================
;Init_8259A===========================================================
Init_8259A:
mov al, 011h
out 020h, al ; 主8259, ICW1.
call IO_Delay
out 0A0h, al ; 从8259, ICW1.
call IO_Delay
mov al, 020h ; IRQ0 对应中断向量 0x20
out 021h, al ; 主8259, ICW2.
call IO_Delay
mov al, 028h ; IRQ8 对应中断向量 0x28
out 0A1h, al ; 从8259, ICW2.
call IO_Delay
mov al, 004h ; IR2 对应从8259
out 021h, al ; 主8259, ICW3.
call IO_Delay
mov al, 002h ; 对应主8259的 IR2
out 0A1h, al ; 从8259, ICW3.
call IO_Delay
mov al, 001h
out 021h, al ; 主8259, ICW4.
call IO_Delay
out 0A1h, al ; 从8259, ICW4.
call IO_Delay
;mov al, 11111111b ; 屏蔽主8259所有中断
mov al, 11111101b ; 仅仅开启键盘中断
out 021h, al ; 主8259, OCW1.
call IO_Delay
mov al, 11111111b ; 屏蔽从8259所有中断
out 0A1h, al ; 从8259, OCW1.
call IO_Delay
ret
;end of Init_8259A====================================================
;IO_Delay=============================================================
IO_Delay:
nop
nop
nop
nop
ret
;end of IO_Delay======================================================
;Disp_Str=============================================================
;函数原型:void Disp_Str(char * pszStr);
;函数功能:在Disp_Pos指示的位置打印一个字符串
Disp_Str:
push ebp
mov ebp,esp
push eax
push ebx
push esi
push edi
mov esi,[ebp + 8] ;取得要显示的字符串的偏移
mov edi,[Disp_Pos]
.begin:
lodsb
test al,al ;如果字符为0就退出
je .exit
cmp al,0ah ;如果是回车则跳到改变esi跳到下一行
jne .disp
push eax
mov eax,edi
mov bl,160
div bl
and ax,0ffh
inc ax
mov bl,160
mul bl
mov edi,eax
pop eax
jmp .begin
.disp:
mov ah,0ch
mov [gs:edi],ax
add edi,2
jmp .begin
.exit:
mov [Disp_Pos],edi ;全局变量赋回值
pop edi
pop esi
pop ebx
pop eax
pop ebp
ret
;end of Disp_Str======================================================
;Disp_Al==============================================================
Disp_Al:
push eax
push ecx
push edi
mov edi,[Disp_Pos]
mov ecx,2
push eax
shr al,4
.loop:
and al,0fh
cmp al,9
ja .letter
add al,'0'
jmp .disp
.letter:
sub al,10
add al,'A'
.disp:
mov ah,0ch
mov [gs:edi],ax
add edi,2
cmp ecx,1
je .exit
pop eax
loop .loop
.exit:
mov [Disp_Pos],edi
pop edi
pop ecx
pop eax
ret
;end of Disp_Al=======================================================
;Disp_32Bit_Int=======================================================
Disp_32Bit_Int:
push ebp
mov ebp,esp
push eax
push esi
mov eax,[ebp + 8]
rol eax,8
call Disp_Al
rol eax,8
call Disp_Al
rol eax,8
call Disp_Al
rol eax,8
call Disp_Al
pop esi
pop eax
pop ebp
ret
;end of Disp_32Bit_Int================================================
Code32_Len equ $ - _start
附图两张:
jmp 80:0 没有注释的情况,一般的保护错误。
键盘中断的情况: