MyOS (二) 将磁盘中的程序装载到内存中

来源:互联网 发布:js数组移除指定元素 编辑:程序博客网 时间:2024/06/04 17:56

(1) Use BIOS interrupt call

Invoking an interrupt

Invoking an interrupt can be done using the INT x86 assembly language instruction. For example, to print a character to the screen using BIOS interrupt 0x10, the following x86 assembly language instructions could be executed:

 mov ah, 0x0e    ; function number = 0Eh : Display Character mov al, '!'     ; AL = code of character to display int 0x10        ; call INT 10h, BIOS video service
用INT指令调用BIOS中的0x13号函数

        MOV        AX,0x0820 
        MOV        ES,AX 
        MOV        CH,0        ; 柱面0 
        MOV        DH,0        ; 磁头0 
        MOV        CL,2        ; 扇区2 
        MOV        AH,0x02     ; 读盘 
        MOV        AL,1        ; 一个扇区 
        MOV        BX,0         
        MOV        DL,0x00     ; A驱动器 
        INT        0x13        ; 调用磁盘BIOS 
        JC         error

在调用BIOS的0x13函数之前,要对对一些寄存器进行初始化,函数根据各个寄存器中不容的值,做出相应的操作。

CYLS    EQU        10 
 
        ORG        0x7c00            ; 程序的装载地址 
 
; 以下的记述用于标准FAT12格式的软盘 

        JMP       entry 
        DB        0x90 
        DB        "HELLOIPL"        ; 启动区的名称可以是任意的字符(8字符) 
        DW        512               ; 每个扇区的大小 
        DB        1                 ; 簇(cluster)的大小(必须为1个扇区) 
        DW        1                 ; FAT的起始位置(一般从第一个扇区开始) 
        DB        2                 ; FAT的个数(必须为2) 
        DW        224               ; 根目录的大小(一般设成224项) 
        DW        2880              ; 该磁盘的大小(必须为2880扇区) 
        DB        0xf0              ; 磁盘的种类(必须是0xf0) 
        DW        9                 ; FAT的长度(必须是9扇区) 
        DW        18                ; 1个磁道(track)有几个扇区(必须是18) 
        DW        2                 ; 磁头数(必须是2) 
        DD        0                 ; 不使用分区,必须是0 
        DD        2880              ; 重写一次磁盘大小 
        DB        0,0,0x29          ; 意义不明,固定 
        DD        0xffffffff        ; (可能是)卷标号码 
        DB        "HELLO-OS   "     ; 磁盘的名称(11字节) 
        DB        "FAT12   "        ; 磁盘格式名称(8字节) 
        RESB      18                ; 先空出18字节        
; 程序核心 
entry: 
        MOV        AX,0             ; 初始化寄存器 
        MOV        SS,AX 
        MOV        SP,0x7c00 
        MOV        DS,AX 
        MOV        ES,AX 
;读磁盘 
        MOV        AX,0x0820 
        MOV        ES,AX 
        MOV        CH,0             ; 柱面0 
        MOV        DH,0             ; 磁头0 
        MOV        CL,2             ; 扇区2      
readloop: 
        MOV        SI,0 
retry:       
        MOV        AH,0x02           ; 读盘 
        MOV        AL,1              ; 1个扇区 
        MOV        BX,0                 
        MOV        DL,0x00           ; A驱动器 
        INT        0x13              ; 调用磁盘BIOS 
        JNC        next 
        ADD        SI,1 
        CMP        SI,5 
        JAE        error 
        MOV        AH,0x00 
        MOV        DL,0x00 
        INT        0x13              ; 这条加上面两条指令是进行“系统复位”,即回复软盘状态 
        JMP        retry 
next:     
        MOV        AX,ES 
        ADD        AX,0X0020 
        MOV        ES,AX 
        ADD        CL,1 
        CMP        CL,18 
        JBE        readloop 
        MOV        CL,1 
        ADD        DH,1 
        CMP        DH,2 
        JB         readloop 
        MOV        DH,0 
        ADD        CH,1 
        CMP        CH,CYLS 
        JB         readloop      
        MOV        [0x0ff0],CH 
        JMP        0xc200 
 
error:     
        MOV        SI,msg 
 
putloop: 
        MOV        AL,[SI] 
        ADD        SI,1              ; 给SI加1 
        CMP        AL,0 
        JE         fin 
        MOV        AH,0x0e           ; 显示一个文字 
        MOV        BX,16             ; 指定字符颜色 
        INT        0x10              ; 调用显卡BIOS 
        JMP        putloop 
fin: 
        HLT                          ; 让CPU停止,等待指令 
        JMP        fin               ; 无限循环 
 
msg: 
        DB         0x0a, 0x0a        ; 换行2次 
        DB         "DUKE OS" 
        DB         0x0a              ; 换行 
        DB         0 
 
      ;  RESB       0x7dfe-$          ; 填写0x00,直到0x07dfe ($代表将要读入的内存地址) 
  times 510-($-$$) DB 0
        DB         0x55, 0xaa 

0 0