实模式下显示字符的引导扇区程序

发表于:2007-06-08来源:作者:点击数: 标签:
1。分两个程序:boot.asm 和 prog.asm其中boot.asm负责将软盘中第2个扇区开始的内容载入内存的 1000:0的地址然后跳转到此。而prog.asm负责进入实模式并输出字符A 2.使用nasm编译,用partcopy拷入软盘(或镜像),用bochs启动。 3.源代码: boot.asm: [org 0x
      

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

原文转自:http://www.ltesting.net