实模式下显示字符的引导扇区程序
1.分两个程序:boot.asm 和 prog.asm其中boot.asm负责将软盘中第2个扇区开始的内容载入内存的 1000:0的地址然后跳转到此。而prog.asm负责进入实模式并输出字符"A"
2.使用nasm编译,用partcopy拷入软盘(或镜像),用bochs启动。
3.源代码:
boot.asm:
[org 0x7c00]
jmp start
start:
mov ax,cs
mov ds,ax
mov es,ax
reset:
;重置软驱
mov ax,0
mov dl,0
int 13h
jc reset
read:
;从第二个扇区开始读,将其后六个扇区的内容读到内存 0x1000:0 的位置
mov ax,1000h
mov es,ax
mov bx,0h
mov ah,2
mov al,6
mov ch,0
mov cl,2
mov dh,0
mov dl,0
int 13h
jc read
jmp 1000h:0h
times 510-($-$$) db 0
dw 0AA55h
prog.asm:
[org 0]
[bits 16]
mov ax,cs
mov ds,ax
jmp init
gdtr :
dw gdt_end-gdt-1 ; gdt的长度
dd gdt+0x10000 ; gdt的物理地址
gdt
gdt0 ; 空描述符
dd 0
dd 0 ; 所有的段描述符都是64位的
codesel equ $-gdt ; 这是8h也就是gdt的第二个描述符
code_gdt ;代码段描述符
dw 0x07ff ; 段描述符的界限是4Gb
dw 0x0000
db 0x01
db 0x09a
db 0x0c0
db 0x00
datasel equ $-gdt
data_gdt ;数据段描述符,这里只是写出来,并没有使用
dw 0x07ff
dw 0x0000
db 0x01
db 0x092
db 0x0c0
db 0x00
videosel equ $-gdt
video_gdt ;视频缓冲区的基址
dw 0xffff
dw 0x8000 ; 基址是0xb8000
db 0x0b
db 0x92
db 0xc0
db 0x00
gdt_end
[bits 16]
init:
mov ebx,0x10000
mov ecx,gdt
protect:
cli
lgdt [gdtr] ;加载GDT
push ax ;开A20线
in al,92h
or al,00000010b
out 92h,al
pop ax
mov eax,cr0 ;置位,切换到保护模式
or al,00000001b
mov cr0,eax
jmp codesel:code_32 ;跳入32位代码
[bits 32]
code_32:
mov ax,videosel
mov gs,ax
mov word[gs:0],0x0741 ;输出白色大写字母'A'
over:
jmp over
times 2048-($-$$) db 0
2.使用nasm编译,用partcopy拷入软盘(或镜像),用bochs启动。
3.源代码:
boot.asm:
[org 0x7c00]
jmp start
start:
mov ax,cs
mov ds,ax
mov es,ax
reset:
;重置软驱
mov ax,0
mov dl,0
int 13h
jc reset
read:
;从第二个扇区开始读,将其后六个扇区的内容读到内存 0x1000:0 的位置
mov ax,1000h
mov es,ax
mov bx,0h
mov ah,2
mov al,6
mov ch,0
mov cl,2
mov dh,0
mov dl,0
int 13h
jc read
jmp 1000h:0h
times 510-($-$$) db 0
dw 0AA55h
prog.asm:
[org 0]
[bits 16]
mov ax,cs
mov ds,ax
jmp init
gdtr :
dw gdt_end-gdt-1 ; gdt的长度
dd gdt+0x10000 ; gdt的物理地址
gdt
gdt0 ; 空描述符
dd 0
dd 0 ; 所有的段描述符都是64位的
codesel equ $-gdt ; 这是8h也就是gdt的第二个描述符
code_gdt ;代码段描述符
dw 0x07ff ; 段描述符的界限是4Gb
dw 0x0000
db 0x01
db 0x09a
db 0x0c0
db 0x00
datasel equ $-gdt
data_gdt ;数据段描述符,这里只是写出来,并没有使用
dw 0x07ff
dw 0x0000
db 0x01
db 0x092
db 0x0c0
db 0x00
videosel equ $-gdt
video_gdt ;视频缓冲区的基址
dw 0xffff
dw 0x8000 ; 基址是0xb8000
db 0x0b
db 0x92
db 0xc0
db 0x00
gdt_end
[bits 16]
init:
mov ebx,0x10000
mov ecx,gdt
protect:
cli
lgdt [gdtr] ;加载GDT
push ax ;开A20线
in al,92h
or al,00000010b
out 92h,al
pop ax
mov eax,cr0 ;置位,切换到保护模式
or al,00000001b
mov cr0,eax
jmp codesel:code_32 ;跳入32位代码
[bits 32]
code_32:
mov ax,videosel
mov gs,ax
mov word[gs:0],0x0741 ;输出白色大写字母'A'
over:
jmp over
times 2048-($-$$) db 0
相关文章
- fedora 9 小集 - 01 05, 2009
- 多线程调试 - 12 17, 2008
- fedora 9 试用 - 12 05, 2008
留言: