INT 0x13 函数

  • 磁盘读、写、扇区检验,以及寻道
  • 需要输入的参数:

    AH=0x02;(读盘)
    AH=0x03;(写盘)
    AH=0x04;(校验)
    AH=0x0c;(寻道)
    AL=处理对象的扇区数;(只能同时处理连续的扇区)
    CH=柱面号 &0xff;
    CL=扇区号(0-5位)|(柱面号&0x300)>>2;
    DH=磁头号;
    DL=驱动器号;
    ES:BX=缓冲地址;(校验及寻道时不使用)

  • 返回值:

    FLAGS.CF == 0; 没有错误,AH == 0
    FLAGS.CF == 1; 有错误,错误号码存入AH内(与重置(reset)功能一样)

寄存器

  • CH、CL、DH、DL分别是柱面号、扇区号、磁头号、驱动器号
  • 驱动器:在有多个软盘驱动器的时候,用磁盘驱动器号来指定从哪个驱动器的软盘上读取数据。现在的电脑,基本都只有1个软盘驱动器,而以前一般都是2个。既然现在只有一个,那不用多想,指定0号就行了。

软盘

  • 结构
  • 柱面:一圈一圈的那个就是
  • 磁头:既可以从软盘正面接触磁盘,也可以从软盘背面接触磁盘。软盘磁盘是两面都能记录数据的,因此我们有正面和反面两个磁头,分别是磁头0号和磁头1号。
  • 扇区:软盘分为18份,每一份称为一个扇区
  • 含有IPL的启动区,位于C0-H0-S1(柱面0,磁头0,扇区1的缩写),下一个扇区是C0-H0-S2

缓冲区地址

  • 附加段寄存器ES
  • 一个BX只能表示0~0xffff,也就是0~65535,最大64K
  • 之后引入的EBX,可以处理4G内存
  • MOV AL, [ES:BX]ES×16+BX
  • 在代码中指定了ES=0x0820BX=0。所以软盘的数据将被装载到内存中0x82000x83ff的地方,0x80000x81ff这512字节是留给启动区的,要将启动区的内容读到那里。
  • 段寄存器DS
  • MOV AL, [SI]相当于MOV AL, [DS:SI]
  • DS必须预先指定为0,否则地址的值就要加上这个数的16倍,就会读写到其他的地方,引起混乱

代码

  • ipl.nas

    ; haribote-ipl
    ; TAB=4ORG     0x7c00          ; 指明程序的装载地址; 以下的记述用于标准FAT12格式的软盘JMP     entryDB     0x90DB      "HARIBOTE"        ; 引导扇区的名称,随意写,8字节DW       512             ; 每个扇区的大小,必须是512DB       1               ; 簇(cluster)的大小,必须为1DW     1               ; FAT起始位置,一般从第一个扇区开始DB       2               ; FAT的个数,必须为2DW      224             ; 根目录大小,一般设置成224DW       2880            ; 磁盘的大小,必须为2880扇区DB      0xf0            ; 磁盘的种类,必须为0xf0DW        9               ; FAT的长度,必须是9扇区DW        18              ; 1个磁道(track)有几个扇区,必须是18DW     2               ; 磁头数,必须为2DD     0               ; 因为不使用分区,所以必须是0字节DD     2880            ; 重写一次磁盘大小,4字节DB     0,0,0x29        ; 意义不明,固定DD      0xffffffff      ; 卷标号DB     "HARIBOTEOS " ; 磁盘名称,11字节DB        "FAT12   "        ; 磁盘格式名称,8字节RESB     18          ; 空出18字节; 核心程序entry:MOV     AX,0            ; 初始化寄存器MOV     SS,AXMOV        SP,0x7c00MOV        DS,AX           ; 段寄存器初始化为0; 僨傿僗僋傪撉傓MOV     AX,0x0820MOV        ES,AX           ; 指定附加段地址寄存器的值0x0820MOV     CH,0            ; 柱面0MOV        DH,0            ; 磁头0MOV        CL,2            ; 扇区2MOV        AH,0x02         ; AH=0x02: 读盘MOV       AL,1            ; 1个扇区MOV       BX,0            ; 指定基址寄存器的值0MOV     DL,0x00         ; A驱动器INT       0x13            ; 调用磁盘BIOSJC        error           ; 如果进位标志是1的话,就跳转; fin 中让CPU停止,进入等待模式,并不断循环
    fin:HLT                     ; 让CPU停止,等待指令JMP     fin             ; 无限循环error:MOV     SI,msg; 不断累加SI中的地址,并从中读取内容。当内容不等于0时,调用中断显示字符,然后重复本步骤;
    ; 当内容为0时,跳转到fin
    putloop:MOV     AL,[SI]ADD      SI,1            ; 给SI加1CMP      AL,0JE      finMOV      AH,0x0e         ; 显示一个文字MOV     BX,15           ; 指定字符颜色INT     0x10            ; 调用显卡BIOSJMP       putloopmsg:DB       0x0a, 0x0a      ; 换行2次DB        "load error"DB        0x0a            ; 换行DB      0RESB   0x7dfe-$        ; 填写0x00,直到0x001feDB     0x55, 0xaa

试错

  • 如果软盘不能读取数据,重试几次,如果一直重试下去,要是磁盘真的坏了,程序就会陷入死循环
  • 部分代码:
  • 完整代码:
    ; haribote-ipl
    ; TAB=4ORG     0x7c00          ; 指明程序的装载地址; 以下的记述用于标准FAT12格式的软盘JMP     entryDB     0x90DB      "HARIBOTE"        ; 引导扇区的名称,随意写,8字节DW       512             ; 每个扇区的大小,必须是512DB       1               ; 簇(cluster)的大小,必须为1DW     1               ; FAT起始位置,一般从第一个扇区开始DB       2               ; FAT的个数,必须为2DW      224             ; 根目录大小,一般设置成224DW       2880            ; 磁盘的大小,必须为2880扇区DB      0xf0            ; 磁盘的种类,必须为0xf0DW        9               ; FAT的长度,必须是9扇区DW        18              ; 1个磁道(track)有几个扇区,必须是18DW     2               ; 磁头数,必须为2DD     0               ; 因为不使用分区,所以必须是0字节DD     2880            ; 重写一次磁盘大小,4字节DB     0,0,0x29        ; 意义不明,固定DD      0xffffffff      ; 卷标号DB     "HARIBOTEOS " ; 磁盘名称,11字节DB        "FAT12   "        ; 磁盘格式名称,8字节RESB     18          ; 空出18字节; 核心程序entry:MOV     AX,0            ; 初始化寄存器MOV     SS,AXMOV        SP,0x7c00MOV        DS,AX           ; 段寄存器初始化为0; 僨傿僗僋傪撉傓MOV     AX,0x0820MOV        ES,AX           ; 指定附加段地址寄存器的值0x0820MOV     CH,0            ; 柱面0MOV        DH,0            ; 磁头0MOV        CL,2            ; 扇区2MOV     SI,0            ; 记录失败次数的寄存器
    retry:MOV       AH,0x02         ; AH=0x02: 读盘MOV       AL,1            ; 1个扇区MOV       BX,0            ; 指定基址寄存器的值0MOV     DL,0x00         ; A驱动器INT       0x13            ; 调用磁盘BIOSJNC       fin             ; 没出错的话跳转到fin,进位标志是0的话就跳转ADD     SI,1            ; 出错往SI加1CMP        SI,5            ; 比较SI和5JAE     error           ; SI >= 5时,跳转到error;JAE大于或等于时跳转MOV        AH,0x00         ; 系统复位”。它的功能是复位软盘状态,再读一次。MOV     DL,0x00         ; A驱动器INT       0x13            ; 重置驱动器JMP      retry; fin 中让CPU停止,进入等待模式,并不断循环
    fin:HLT                     ; 让CPU停止,等待指令JMP     fin             ; 无限循环error:MOV     SI,msg; 不断累加SI中的地址,并从中读取内容。当内容不等于0时,调用中断显示字符,然后重复本步骤;
    ; 当内容为0时,跳转到fin
    putloop:MOV     AL,[SI]ADD      SI,1            ; 给SI加1CMP      AL,0JE      finMOV      AH,0x0e         ; 显示一个文字MOV     BX,15           ; 指定字符颜色INT     0x10            ; 调用显卡BIOSJMP       putloopmsg:DB       0x0a, 0x0a      ; 换行2次DB        "load error"DB        0x0a            ; 换行DB      0RESB   0x7dfe-$        ; 填写0x00,直到0x001feDB     0x55, 0xaa
    

读到18扇区

  • 如果要读取下一扇区,只需给CL加1,给ES加上0x20

    ; haribote-ipl
    ; TAB=4ORG     0x7c00          ; 指明程序的装载地址; 以下的记述用于标准FAT12格式的软盘JMP     entryDB     0x90DB      "HARIBOTE"        ; 引导扇区的名称,随意写,8字节DW       512             ; 每个扇区的大小,必须是512DB       1               ; 簇(cluster)的大小,必须为1DW     1               ; FAT起始位置,一般从第一个扇区开始DB       2               ; FAT的个数,必须为2DW      224             ; 根目录大小,一般设置成224DW       2880            ; 磁盘的大小,必须为2880扇区DB      0xf0            ; 磁盘的种类,必须为0xf0DW        9               ; FAT的长度,必须是9扇区DW        18              ; 1个磁道(track)有几个扇区,必须是18DW     2               ; 磁头数,必须为2DD     0               ; 因为不使用分区,所以必须是0字节DD     2880            ; 重写一次磁盘大小,4字节DB     0,0,0x29        ; 意义不明,固定DD      0xffffffff      ; 卷标号DB     "HARIBOTEOS " ; 磁盘名称,11字节DB        "FAT12   "        ; 磁盘格式名称,8字节RESB     18          ; 空出18字节; 核心程序entry:MOV     AX,0            ; 初始化寄存器MOV     SS,AXMOV        SP,0x7c00MOV        DS,AX           ; 段寄存器初始化为0; 僨傿僗僋傪撉傓MOV     AX,0x0820MOV        ES,AX           ; 指定附加段地址寄存器的值0x0820MOV     CH,0            ; 柱面0MOV        DH,0            ; 磁头0MOV        CL,2            ; 扇区2readloop:MOV     SI,0            ; 记录失败次数的寄存器retry:MOV     AH,0x02         ; AH=0x02: 读盘MOV       AL,1            ; 1个扇区MOV       BX,0            ; 指定基址寄存器的值0MOV     DL,0x00         ; A驱动器INT       0x13            ; 调用磁盘BIOSJNC       next            ; 没出错时跳转到nextADD        SI,1            ; 往SI加1CMP      SI,5            ; 比较SI与5JAE     error           ; SI >= 5时,跳转到errorMOV       AH,0x00MOV      DL,0x00         ; A驱动器INT       0x13            ; 重置驱动器JMP      retry
    next:MOV        AX,ES           ; 把内存地址后移0x200ADD       AX,0x0020MOV        ES,AX           ; 因为没有ADD ES,0x020指令,所以这里稍微绕个弯ADD        CL,1            ; 往CL里加1CMP     CL,18           ; 比较CL与18JBE        readloop        ; 如果CL <= 18 跳转至readloop; fin 中让CPU停止,进入等待模式,并不断循环
    fin:HLT                     ; 让CPU停止,等待指令JMP     fin             ; 无限循环error:MOV     SI,msg; 不断累加SI中的地址,并从中读取内容。当内容不等于0时,调用中断显示字符,然后重复本步骤;
    ; 当内容为0时,跳转到fin
    putloop:MOV     AL,[SI]ADD      SI,1            ; 给SI加1CMP      AL,0JE      finMOV      AH,0x0e         ; 显示一个文字MOV     BX,15           ; 指定字符颜色INT     0x10            ; 调用显卡BIOSJMP       putloopmsg:DB       0x0a, 0x0a      ; 换行2次DB        "load error"DB        0x0a            ; 换行DB      0RESB   0x7dfe-$        ; 填写0x00,直到0x001feDB     0x55, 0xaa
  • 一个扇区的大小是512,要读取下一个扇区,就得给CL加上1,给ES加上0x20(521 / 16)。因为 MOV AL, [ES:BX]ES × 16 + BX = 512BX = 0ES = 512 / 16;其实也可以写成BX + 512
  • 这里不是非要用循环,在调用读盘函数INT 0x13的地方,只要将AL的值设置成17就行了。这样,程序一下子就能将扇区2~18共17个扇区的数据完整的读进来。

读入10个柱面

  • 程序:

    ; haribote-ipl
    ; TAB=4
    CYLS    EQU     10              ; 相当于C语言的#define命令,用来声明常数,CYLS = 10。ORG      0x7c00          ; 指明程序的装载地址; 以下的记述用于标准FAT12格式的软盘JMP     entryDB     0x90DB      "HARIBOTE"        ; 引导扇区的名称,随意写,8字节DW       512             ; 每个扇区的大小,必须是512DB       1               ; 簇(cluster)的大小,必须为1DW     1               ; FAT起始位置,一般从第一个扇区开始DB       2               ; FAT的个数,必须为2DW      224             ; 根目录大小,一般设置成224DW       2880            ; 磁盘的大小,必须为2880扇区DB      0xf0            ; 磁盘的种类,必须为0xf0DW        9               ; FAT的长度,必须是9扇区DW        18              ; 1个磁道(track)有几个扇区,必须是18DW     2               ; 磁头数,必须为2DD     0               ; 因为不使用分区,所以必须是0字节DD     2880            ; 重写一次磁盘大小,4字节DB     0,0,0x29        ; 意义不明,固定DD      0xffffffff      ; 卷标号DB     "HARIBOTEOS " ; 磁盘名称,11字节DB        "FAT12   "        ; 磁盘格式名称,8字节RESB     18          ; 空出18字节; 核心程序entry:MOV     AX,0            ; 初始化寄存器MOV     SS,AXMOV        SP,0x7c00MOV        DS,AX           ; 段寄存器初始化为0; 僨傿僗僋傪撉傓MOV     AX,0x0820MOV        ES,AX           ; 指定附加段地址寄存器的值0x0820MOV     CH,0            ; 柱面0MOV        DH,0            ; 磁头0MOV        CL,2            ; 扇区2readloop:MOV     SI,0            ; 记录失败次数的寄存器retry:MOV     AH,0x02         ; AH=0x02: 读盘MOV       AL,1            ; 1个扇区MOV       BX,0            ; 指定基址寄存器的值0MOV     DL,0x00         ; A驱动器INT       0x13            ; 调用磁盘BIOSJNC       next            ; 没出错时跳转到nextADD        SI,1            ; 往SI加1CMP      SI,5            ; 比较SI与5JAE     error           ; SI >= 5时,跳转到errorMOV       AH,0x00MOV      DL,0x00         ; A驱动器INT       0x13            ; 重置驱动器JMP      retry
    next:MOV        AX,ES           ; 把内存地址后移0x200ADD       AX,0x0020MOV        ES,AX           ; 因为没有ADD ES,0x020指令,所以这里稍微绕个弯ADD        CL,1            ; 往CL里加1CMP     CL,18           ; 比较CL与18JBE        readloop        ; 如果CL <= 18 跳转至readloopMOV     CL,1ADD     DH,1            ; 更改磁头的位置CMP        DH,2JB      readloop        ; DH < 2 跳转到readloopMOV      DH,0            ; 将磁头的位置变为0ADD      CH,1            ; 跳到下一个柱面CMP        CH,CYLS         ; 宏定义 CYLS = 10JB      readloop        ; CH < CYLS 跳转到readloop; fin 中让CPU停止,进入等待模式,并不断循环
    fin:HLT                     ; 让CPU停止,等待指令JMP     fin             ; 无限循环error:MOV     SI,msg; 不断累加SI中的地址,并从中读取内容。当内容不等于0时,调用中断显示字符,然后重复本步骤;
    ; 当内容为0时,跳转到fin
    putloop:MOV     AL,[SI]ADD      SI,1            ; 给SI加1CMP      AL,0JE      finMOV      AH,0x0e         ; 显示一个文字MOV     BX,15           ; 指定字符颜色INT     0x10            ; 调用显卡BIOSJMP       putloopmsg:DB       0x0a, 0x0a      ; 换行2次DB        "load error"DB        0x0a            ; 换行DB      0RESB   0x7dfe-$        ; 填写0x00,直到0x001feDB     0x55, 0xaa
    

着手开发操作系统

  • 之前写的不是操作系统,只是操作系统的启动区,被用来把操作系统装载到内存中
  • 新建一个文本文档并命名为haribote.nas
    fin:HLTJMP fin
    
  • 因为新添了文件,需要在Makefile中规定它的编译规则
    TOOLPATH = ../z_tools/
    MAKE     = $(TOOLPATH)make.exe -r
    NASK     = $(TOOLPATH)nask.exe
    EDIMG    = $(TOOLPATH)edimg.exe
    IMGTOL   = $(TOOLPATH)imgtol.com
    COPY     = copy
    DEL      = deldefault :$(MAKE) img# 启动区文件
    # ipl.nas —> ipl.bin
    ipl.bin : ipl.nas Makefile$(NASK) ipl.nas ipl.bin ipl.lst# 操作系统本身的内容
    # haribote.nas —> haribote.sys
    haribote.sys : haribote.nas Makefile$(NASK) haribote.nas haribote.sys haribote.lst# 操作系统镜像文件
    # ipl.bin & haribote.sys —> haribote.img
    haribote.img : ipl.bin haribote.sys Makefile$(EDIMG)   imgin:../z_tools/fdimg0at.tek \wbinimg src:ipl.bin len:512 from:0 to:0 \copy from:haribote.sys to:@: \imgout:haribote.img# 僐儅儞僪img :$(MAKE) haribote.imgrun :$(MAKE) img$(COPY) haribote.img ..\z_tools\qemu\fdimage0.bin$(MAKE) -C ../z_tools/qemuinstall :$(MAKE) img$(IMGTOL) w a: haribote.imgclean :-$(DEL) ipl.bin-$(DEL) ipl.lst-$(DEL) haribote.sys-$(DEL) haribote.lstsrc_only :$(MAKE) clean-$(DEL) haribote.img
    
  • 输入make run
  • 打开haribote.img,可以发现在0x2600地址附近保存着文件名。在0x4200地址附近,看到“F4 EB FD”。

  • 以上内容可以总结为:一般向一个空软盘保存文件时
    (1)文件名会写在0x2600以后的地方;
    (2)文件的内容会写在0x4200以后的地方。

从启动区执行操作系统

  • 如何执行磁盘映像上位于0x004200号地址的程序
  • 程序是从启动区开始,把磁盘上的内容装载到内存0x8000号地址,所以磁盘0x4200处的内容就应该位于内存0x8000+0x4200=0xc200号地址
  • haribote.nas中加上ORG 0xc200
    ; haribote-os
    ; TAB=4ORG     0xc200          ; 这个程序将要被装载到内存的什么地方MOV      AL,0x13         ; VAG显卡,320x200x8位色彩MOV      AH,0x00         ; 设定AH=0x00后,调用显卡的BIOS函数INT     0x10
    fin:HLTJMP      fin
    
  • 设置显卡模式:
  • 输入make run

32位模式前期准备

  • CPU有16位和32位两种模式:
    以16位模式启动的话,用AX和CX等16位寄存器会非常方便
    16位模式的机器语言在32位模式下不能运行
    32位模式下可以使用的内存容量远远大于1MB
    CPU的自我保护功能(识别出可疑的机器语言并进行屏蔽,以免破坏系统)在16位下不能用,但32位下能用
    32位模式下不能调用BIOS功能。因为BIOS是用16位机器语言写的。如果我们有什么事情想用BIOS来做,那就全部都放在开头先做
  • 想从BIOS得到键盘状态。所谓键盘状态,是指NumLock是ON还是OFF等这些状态
  • 修改haribote.nas
    ; haribote-os
    ; TAB=4; 有关BOOT_INFO
    CYLS    EQU     0x0ff0          ; 设定启动区
    LEDS    EQU     0x0ff1
    VMODE   EQU     0x0ff2          ; 关于颜色数目的信息。颜色的位数
    SCRNX   EQU     0x0ff4          ; 分辨率X(screen x)
    SCRNY   EQU     0x0ff6          ; 分辨率Y(screen y)
    VRAM    EQU     0x0ff8          ; 图像缓冲区的开始地址ORG     0xc200          ; 这个程序将要被装载到内存的什么地方MOV      AL,0x13         ; VGA显卡,320x200x8位色彩INT      0x10MOV     BYTE [VMODE],8  ; 记录画面模式,把画面模式的信息保存在了内存里MOV      WORD [SCRNX],320MOV     WORD [SCRNY],200MOV     DWORD [VRAM],0x000a0000 ; VRAM指的是显卡内存,VRAM的各个地址都对应着画面上的象素,可以绘制出图案; 不同画面模式的像素数/内存也不一样,所以需要预先把要使用的VRAM地址保存在BOOT_INFO里以备用; 用BIOS取得键盘上各种LED指示灯的状态MOV       AH,0x02INT      0x16            ; keyboard BIOSMOV      [LEDS],ALfin:HLTJMP     fin
    

开始导入C语言

  • 将原来的haribote.nas改为asmhead.nas
    前半部分是用汇编语言写的,后半部分是用C语言写的
    为了调用C语言写的程序,添加了100行左右的汇编代码
  • C语言
    void HariMain(void) {fin:/* 这里想写上HLT,但C原因呢中不能用HLT */// goto指令是新出现的,相当于汇编语言中的JMP,实际上也是被编译成JMP指令goto fin;
    }
    
  • 修改Makefile文件

    TOOLPATH = ../z_tools/
    INCPATH  = ../z_tools/haribote/MAKE     = $(TOOLPATH)make.exe -r
    NASK     = $(TOOLPATH)nask.exe
    CC1      = $(TOOLPATH)cc1.exe -I$(INCPATH) -Os -Wall -quiet
    GAS2NASK = $(TOOLPATH)gas2nask.exe -a
    OBJ2BIM  = $(TOOLPATH)obj2bim.exe
    BIM2HRB  = $(TOOLPATH)bim2hrb.exe
    RULEFILE = $(TOOLPATH)haribote/haribote.rul
    EDIMG    = $(TOOLPATH)edimg.exe
    IMGTOL   = $(TOOLPATH)imgtol.com
    COPY     = copy
    DEL      = deldefault :$(MAKE) img# 僼傽僀儖惗惉婯懃ipl10.bin : ipl10.nas Makefile$(NASK) ipl10.nas ipl10.bin ipl10.lstasmhead.bin : asmhead.nas Makefile$(NASK) asmhead.nas asmhead.bin asmhead.lstbootpack.gas : bootpack.c Makefile$(CC1) -o bootpack.gas bootpack.cbootpack.nas : bootpack.gas Makefile$(GAS2NASK) bootpack.gas bootpack.nasbootpack.obj : bootpack.nas Makefile$(NASK) bootpack.nas bootpack.obj bootpack.lstbootpack.bim : bootpack.obj Makefile$(OBJ2BIM) @$(RULEFILE) out:bootpack.bim stack:3136k map:bootpack.map \bootpack.obj
    # 3MB+64KB=3136KBbootpack.hrb : bootpack.bim Makefile$(BIM2HRB) bootpack.bim bootpack.hrb 0haribote.sys : asmhead.bin bootpack.hrb Makefilecopy /B asmhead.bin+bootpack.hrb haribote.sysharibote.img : ipl10.bin haribote.sys Makefile$(EDIMG)   imgin:../z_tools/fdimg0at.tek \wbinimg src:ipl10.bin len:512 from:0 to:0 \copy from:haribote.sys to:@: \imgout:haribote.img# 僐儅儞僪img :$(MAKE) haribote.imgrun :$(MAKE) img$(COPY) haribote.img ..\z_tools\qemu\fdimage0.bin$(MAKE) -C ../z_tools/qemuinstall :$(MAKE) img$(IMGTOL) w a: haribote.imgclean :-$(DEL) *.bin-$(DEL) *.lst-$(DEL) *.gas-$(DEL) *.obj-$(DEL) bootpack.nas-$(DEL) bootpack.map-$(DEL) bootpack.bim-$(DEL) bootpack.hrb-$(DEL) haribote.syssrc_only :$(MAKE) clean-$(DEL) haribote.img
    
  • 解释文件作用
  • cc1是C编译器,可以将C语言程序编译成汇编语言源程序,输出的是gas用的源程序。它不能翻译成nask。
  • gas2nask可以把gas变换成nask
  • 使用nask制作obj文件。obj文件又称为目标文件
  • 目标文件是一种特殊的机器语言文件,必须与其他文件链接(link)后才能变成真正可以执行的机器语言
  • 为了能做成完整的机器语言文件,必须将必要的目标文件全部链接上。完成这项工作的,就是obj2bim
  • 映像文件:映像文件即不是文件本来的状态,而是一种代替形式
  • bim文件也“不是本来的状态,而是一种代替的形式”,也还不是完成品。这只是将各个部分全部都链接在一起,做成了一个完整的机器语言文件,而为了能实际使用,我们还需要针对每一个不同操作系统的要求进行必要的加工,比如说加上识别用的文件头,或者压缩等
  • 函数名HariMain非常重要,程序就是从以HariMain命名的函数开始运行的,所以这个函数名不能更改

实现HLT

  • 就是让程序处于那个不耗电的状态
  • 创建文件naskfunc.nas
  • 用汇编写的函数,之后还要与bootpack.obj链接,所以也需要编译成目标文件。因此将输出格式设定为WCOFF模式。另外,还要设定成32位机器语言模式
  • 函数名的前面加上“_”,否则就不能很好地与C语言函数链接
  • RET指令,相当于C语言的return
  • 修改bootpack.c

遇到的问题及解决方法

  • ORG命令后的地址是什么地址?
    ORG后的地址是程序被载入内存时的起始地址;在我们的实验代码中,org指令本身并不能决定程序将要加载到内存的什么位置,它只是告诉编译器,我的程序在编译好后需要加载到哪个地址;(因为只有编译才会逐行读取里面代码)
  • 码中为什么总是使用ORG
    0x7c00?
    引导程序加载到内存的7c00h处是一项标准,并不是在编程时决定的,在实际装系统的过程中(并非是虚拟机),将org后的数字改成其他值,bois程序一样将它加载到7c00处;
  • 为什么有时候去掉ORG指定地址或者使用7c00后的地址后还可以正常执行吗?
    ORG相当于段地址;不一定。在数据访问时,都是采用段地址+基址的方式,如果不用org指定地址那么段地址就会清0,最后读取数据的地址就不是我们预期的那个地址了;当程序中没有对内存的寻址操作时,不加org
    0x7c00就不会出错。
  • 如果说ORG指令后的地址是启动区的装载地址,那么ORG以及之前的指令被加载内存的什么地方?
    org指令只会在编译期影响到内存寻址指令的编译(编译器会把所有程序用到的段内偏移地址自动加上org后跟的数值),而其自身并不会被编译成机器码。
  • 为什么0x8000到0x81ff区域也要留给启动区,而且为什么不是从0x7e00开始?

    解决方法:经过查阅了一些资料得知,BIOS读完启动扇区以后,会跳转到0x7C00启动,占用0x7C00-0x7DFF这一段(512字节),而一般bootloader还需要一个栈空间或者读磁盘的交换空间,一般是放到0x7E00-0x7FFF这512字节里,所以有些操作系统的镜像起点是0x8000。然后启动区确实会拷贝一份映射到0x8000位置上。但是BIOS里读取启动扇区都是加载到0x7C00上的。

Day3——自制操作系统相关推荐

  1. 《30天自制操作系统》-day3(MAC)

    第3天 进入32位模式并导入C语言 基本配置 汇编语言内容 文件 hanbote.nas ipl.nas Makefile 原因 用法 基本配置 设备:Macbookpro(13-inch,2018) ...

  2. c语言自制驱动程序,自制操作系统10-自已搭建制作工具

    在第三篇文章我想用nasm与c来开发我们的操作系统,但当时最终还是用了作者现成的工具做的镜像文件.在学完汇编语言后,再来尝试. 1.汇编语言的引导程序.第二天虽然已经实现了用汇编语言编写hello w ...

  3. 为什么《30天自制操作系统》封面中的猫是两只尾巴

    刚刚在一社区,发了一贴,被指出一问题,询一高人,得一答案.这便是我没有关注到的封面上的那只猫,我想这也是很多读者没有关注到的.因为在我微博的200转发贴中,并没有人提到封面中的猫为何有两只尾巴.于是咨 ...

  4. 发布在《30天自制操作系统》之前的帮助阅读贴

    说明:这是8月15日即将上市的一本新书,本文的摘选也可以命名为<30天自制操作系统>上市之前必读.本书幽默,有趣,可以说是技术书里的幽默书,让您读起来绝对不会感到乏味.在本书上市之前,您一 ...

  5. 如何读emmc里的引导程序_自制操作系统学习1 引导程序

    本系列学习有前面的汇编学习基础最好,如果没有影响也不大本系列学习主要资源来自<[30天自制操作系统].(川合秀实)>,<自己动手写操作系统>两本书 一.准备工作 bochs v ...

  6. 《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!

    <30天自制操作系统>笔记(01)--hello bitzhuwei's OS! 最初的OS代码 1 ; hello-os 2 ; TAB=4 3 4 ORG 0x7c00 ; 指明程序的 ...

  7. 写在《30天自制操作系统》上市之前

       这本<30天自制操作系统>马上就要在各大书店和网上商城全面上架了,作为本书的4位译者之一,我负责翻译了本书约三分之二的内容.这是我参与翻译的第一本译著,我感到很激动也很紧张,因为我知 ...

  8. 自制操作系统(十) 图像叠加处理

    2016.07.12 参考书籍:<30天自制操作系统>.<自己动手写操作系统> qq:992591601  欢迎交流 图像叠加处理的原理很简单,就是给图像分层,从低下往上面画, ...

  9. 《30天自制操作系统》笔记(04)——显示器256色

    <30天自制操作系统>笔记(04)--显示器256色 进度回顾 从最开始的(01)篇到上一篇为止,已经解决了开发环境问题和OS项目的顶层设计问题. 本篇做一个小练习:设置显卡显示256色. ...

最新文章

  1. php数据库html文本,关于php,mysql,html的数字分页和文本_php
  2. C程序设计的抽象思维-递归过程-砝码称重
  3. aspx-cs-dll :在部署后就让所有的aspx处于已经编译成dll的状态
  4. 广域网安全建设的思路和部署
  5. MFC 单文档的全局变量
  6. 测验3: 基本数据类型 (第3周)
  7. 会计期间变式OB52
  8. 卸载chrome_Chrome 浏览器必备“扩展管理工具”,一键管理 Chrome 扩展
  9. WEKA “Detailed Accuracy By Class”和“Confusion Matrix”含义
  10. python encode函数_关于字符串:在python中使用unicode()和encode()函数
  11. 【机器人学习】abb机器人运动学分析与轨迹规划(三维模型+matlab代码+word报告)
  12. 陕西计算机在职研究生院校排名,陕西在职研究生哪个学校好上
  13. pthread_cond_destroy死锁卡住问题处理记录
  14. (翻译)角色扮演模式(Role playing)
  15. X猫免费小说安卓逆向分析
  16. 海龟编辑器怎么运行html,海龟编辑器绘制五角星的操作流程
  17. 浅谈基于PLC和Modbus的配电室现场环境监控系统设计及产品选型
  18. python-pcl函数_Python简介,第4章-函数
  19. 互联网公司程序员完整的晋升路径!
  20. crond atd 定时处理

热门文章

  1. vue.js项目中配置mapbox可视化地图api
  2. 视觉设计师输出内容(IOS)
  3. 飞瞳引擎™集装箱人工智能AI识别检测云服务,集装箱人工智能集装箱残损检测信息识别,全球港航人工智能/集装箱人工智能领军者中集飞瞳
  4. 包邮送一台高配置联想电脑,跑虚拟机无压力
  5. Nlog 使用教程(C#)
  6. 天猫魔盒远程安装APP
  7. android 仿微信demo————微信顶部操作栏加号按钮实现(弹出子菜单)
  8. Progressive Tree-Based Compression of Large-Scale Particle Data | 学习笔记
  9. SAP-PP知识分享-PP常用表积累
  10. 冒三鲜冒菜分享香气溢人 自制冒菜