从实地址模式进入保护地址模式.
请给一个已经调试通过的程序.
网上的这类程序很多,但我的编译器通不过.MASM611.
我初学汇编,需要简洁,无误的范例.
有劳各位.
[解决办法]
这是我写的引导代码中切入保护模式的部分,LZ可以参考一下,不过语法是nasm的
cli
enable_A20:
call empty_8042;we must wait until the buffer is empty
mov al,0xd1
out 0x64,al
call empty_8042
mov al,0xdf
out 0x60,al
call empty_8042
;Now the A20 gate has been enabled
;we must reprogram 8259A
;Intel has reserved interrupt vector 0x00-0x1f,
;however, IBM set the vector for 8259A at 0x08.
;it 's really a mass.
;so we must reprogram it:)
mov al,0x11;ICW1
out 0x20,al;send it to 8259A-master
dw 0x00eb,0x00eb;delay
out 0xa0,al;send it to 8259A-slave
dw 0x00eb,0x00eb;delay
mov al,0x20;ICW2,interrupt vector
out 0x21,al;send it to master
dw 0x00eb,0x00eb;delay
mov al,0x28
out 0xa1,al;send it to slave
dw 0x00eb,0x00eb;delay
mov al,0x04
out 0x21,al;set master
dw 0x00eb,0x00eb;delay
mov al,0x02
out 0xa1,al;set slave
dw 0x00eb,0x00eb;delay
mov al,0x01;ICW4
out 0x21,al;sent it to master
dw 0x00eb,0x00eb;delay
out 0xa1,al;sent it to slave
dw 0x00eb,0x00eb;delay
mov al,0xff;mask off all interrupt for now
out 0x21,al;for master
dw 0x00eb,0x00eb;delay
out 0xa1,al;for slave
;OK,it 's really a mass:(
;now load gdt and idt
lgdt [gdt_48]
lidt [idt_48]
;now we should change the mode
;and it 's simple
mov ax,0x0001
lmsw ax;that 's it
db 0x66,0xea;we need a jump
code32: dd 0x90800
dw 0x0008
next:
die:
jmp die
;*******************************************************************
;this is the routine empty_8042
empty_8042:
dw 0x00eb,0x00eb;it 's for the delay
in al,0x64;8042 status port
test al,2;is buffer empty
jnz empty_8042
ret
;*******************************************************************
gdt:
;The gdt data stucture is as follows
;word1 limit(bit 0 - bit 15)
;word2 base (bit 0 - bit 15)
;word3 present bit, DPL bits(2 bits), S bit, Type (4 bits), base(bit 16 - bit 23)
;word4 base(bit 24- bit 31), G bit, D/B bit, Zero bit, AVL bit, limit(bit 16 - bit 19)
dw 0,0,0,0;dummy
;this is the kernel cs, refered by 0x08
dw 0xffff;limit = 0xffff
dw 0x0000;base = 0x0000
dw 0x9A00;present=1, DPL=00, style=1, base=0x00,1001,1010,0000,0000b
dw 0x00Cf;base = 0x00, G=1, D/B=1, AVL=00, limit=f0000,0000,1100,1111b
;this is the kernel ds, refered by 0x10
dw 0xffff;limit = 0xffff
dw 0x0000;base = 0x0000
dw 0x9200;present=1, DPL=00, style=1, base=0x00,1001,0010,0000,0000b
dw 0x00Cf;base = 0x00, G=1, D/B=1, AVL=00, limit=f0000,0000,1100,1111b
;this is the user cs, refered by 0x1b
dw 0xffff;limit = 0xffff
dw 0x0000;base = 0x0000
dw 0xfA00;present=1, DPL=00, style=1, base=0x00,1111,1010,0000,0000b
dw 0x00Cf;base = 0x00, G=1, D/B=1, AVL=00, limit=f0000,0000,1100,1111b
;this is the user ds, refered by 0x23
dw 0xffff;limit = 0xffff
dw 0x0000;base = 0x0000
dw 0xf200;present=1, DPL=11, style=1, base=0x00,1111,0010,0000,0000b
dw 0x00Cf;base = 0x00, G=1, D/B=1, AVL=00, limit=f0000,0000,1100,1111b
;reserved for tss
dw 0x0068;limit = 0xffff
dw 0x0000;base = 0x0000
dw 0x8900;presnet=1,DPL=0x11,0,style=1001,base = 0x001000,1001,0000,0000
dw 0x0080;base = 0x00,G=1,0,0,AVL=0,limit=0;0000,0000,1000,0000
idt_48:
;this is the temporary idt
dw 0,;limit
dw 0,0;base
gdt_48:
;this is the gdt base and limit
dw 0x0800;gdt limit = 2048
dw gdt, 0x9;gdt base
msg1: db "Loading... "