代码拉取完成,页面将自动刷新
; haribote-ipl
; TAB=4
; 一般向一个空软盘保存文件时
; (1) 文件名会写在0x002600以后的地方;
; (2) 文件的内容会写在0x004200以后的地方。
CYLS EQU 10 ; 即CYLS=10,定义了10个柱面
; EQU 声明常数,相当于C语言的#define
ORG 0x7c00 ; 指明程序的装载地址,IBM规定:0x00007c00 - 0x00007dff 启动区内容的装载地址
; 以下格式是标准FAT12格式软盘专用代码
JMP entry ; JMP entry也可写成JMP 0x7c50,因为entry地址位0x7c50
DB 0x90 ; DB 0xeb,0x4e,0x90替换为以上三个指令
DB "HARIBOTE" ; 启动扇区名称8字节
DW 512 ; 每个扇区( sector)的大小(必须为512字节)
DB 1 ; 簇( cluster)的大小(必须为1个扇区)
DW 1 ; FAT的起始位置(一般从第一个扇区开始)
DB 2 ; FAT的个数(必须为2)
DW 224 ; 根目录的大小(一般设成224项)
DW 2880 ; 该磁盘的大小(必须是2880扇区),一张软盘1440kb,除以512字节的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 "HARIBOTEOS " ; 磁盘的名称(11字节)
DB "FAT12 " ; 磁盘格式名称(8字节)
RESB 18 ; 先空出18字节
; JMP x 跳转到指定地址
; 程序主体
entry:
MOV AX,0 ; 初始化寄存器
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX
; MOV ES,AX
; MOV SI,msg
; MOV x,y 相当于 x=y
; 读磁盘,把软盘最初的10× 2× 18× 512=184320 byte=180KB内容完整无误地装载到内存里
MOV AX,0x0820 ; 指定了ES=0x0820, BX=0,所以软盘的数据将被装载到内存中0x08200~0x34fff的地方
MOV ES,AX
MOV CH,0 ; 柱面0
MOV DH,0 ; 磁头0
MOV CL,2 ; 扇区2
readloop:
MOV SI,0 ; 记录失败次数的寄存器
retry:
MOV AH,0x02 ; AH=0x02 读盘
MOV AL,1 ; 1个扇区
MOV BX,0
MOV DL,0x00 ; A驱动器
INT 0x13 ; 调用磁盘bios
JNC next ; 没出错跳转到next
ADD SI,1 ; SI+1
CMP SI,5 ; 比较SI与5
JAE error ; SI>=5跳转到error
MOV AH,0x00
MOV DL,0x00 ; A驱动器
INT 0x13 ; 重置驱动器
JMP retry
; INT 软件中断指令
; JNC 条件跳转,进位标志为0就跳转
; JAE 大于等于跳转
; AH=0x02(读盘)AH=0x03(写盘)AH=0x04(校验)AH=0x0c(寻道)AL=处理对象的扇区数(只能同时处理连续的扇区)
; CH=柱面号 &0xff;CL=扇区号(0-5位)|(柱面号&0x300)>>2;DH=磁头号;DL=驱动器号
; 返回值:FLACS.CF==0:没有错误,AH==0FLAGS.CF==1:有错误,错误号码存入AH内(与重置(reset)功能一样)
; FLAGS.CF是进位标志.调用函数后,如果没有错,进位标志就是0;如果有错,进位标志就是1。
; 进位标志是一个只能存储1位信息的寄存器,像这种1位寄存器称之为标志,英文为flag
; 含有IPL的启动区,位于C0-H0-S1(柱面0,磁头0,扇区1的缩写),下一个扇区是C0-H0-S2
; ES:BX=缓冲地址;(校验及寻道时不使用)用一个寄存器来表示内存地址很方便,但一个BX只能表示0~0xffff的值,0~65535最大64K
; 使用段寄存器时,以ES:BX这种方式来表示地址,写成“MOV AL, [ES:BX]”,它代表ES×16+BX的内存地址。可以理解ES寄存器指定大致的地址,再用BX来指定具体地址。
; 指定内存的什么地址,都必须同时指定段寄存器,这是规定。一般如果省略的话就会把“DS:”作为默认的段寄存器。
; “MOV CX, [1234]”,其实是“MOV CX, [DS:1234]”,MOV AL, [SI]”,也就是“MOV AL, [DS:SI]”的意思。
; 可以省略默认的段寄存器DS。所以DS必须预先指定为0,否则地址的值就要加上这个数的16倍
; AH=0x00, DL=0x00, INT 0x13 是“系统复位”。它的功能是复位软盘状态,再读一次。
next:
MOV AX,ES ; 将内存地址后移0x200
ADD AX,0x0020
MOV ES,AX ; 没有ADD ES,0x20 ,用AX相加后赋值
ADD CL,1 ; 往CL即扇区加1
CMP CL,18 ; 与18比较
JBE readloop ; <=18则跳转到readloop
MOV CL,1
ADD DH,1
CMP DH,2
JB readloop ; 如果DH<2则跳转到readloop
MOV DH,0
ADD CH,1
CMP CH,CYLS
JB readloop ; 如果CH<CYLS则跳转到readloop
; JB jump if below 小于则跳转
; JBE 小于等于跳转
; CYLS
; 要读下一个扇区,只需给CL加1,给ES加上0x20就行了。CL是扇区号,ES指定读入地址。ES x 16 即0x20 x 16 =512
; 磁盘上C0-H0-S2到C0-H0-S18的512×17=8704字节的内容,装载到了内存的0x8200~0xa3ff处。
; JMP 0xc200之前,加入了一行命令,将CYLS的值写到内存地址0x0ff0中
MOV [0x0ff0],CH ; 0x0ff0是用来保存程序的数据,相当于声明变量,分配内存地址。
JMP 0xc200
; 0x0000 - 0x03ff 中断向量表
; 0x0400 - 0x04ff BIOS数据区
; 0x0500 - 0x7bff 自由内存区
; 0x7c00 - 0x7dff 引导程序加载区
; fin 表示结束
fin:
HLT ; 让cpu停止,等待指令
JMP fin ; 无限循环
; HLT 让cpu进入待机状态,只要外部变化,如按键,cpu则会继续执行。JMP fin也可无限循环,但会让cpu无意义的空转,负荷达到100%
error:
MOV SI,msg
putloop:
MOV AL,[SI] ; 将SI地址的1字节内容存入AL
ADD SI,1 ; SI=SI+1
CMP AL,0 ; 将AL的值与0比较
JE fin ; 比较相等则跳转到指定地址,不相等则执行下一条指令
MOV AH,0x0e ; 显示一个文字
MOV BX,15 ; 指定字符颜色
INT 0x10 ; 调用显卡bios
JMP putloop
; [] 表示内存地址,MOV BYTE [278],123 用内存278地址保存123数值
; CMP x,x 比较值,相等则跳转
; 信息显示部分
msg:
DB 0x0a, 0x0a ; 换行2次
DB "load error"
DB 0x0a ; 换行
DB 0
RESB 0x7dfe-$ ; 填写0x00直到0x7dfe
DB 0x55, 0xaa ; 第一个扇区最后两个字节为0x55 aa,则认为这个扇区的开头是启动程序并执行该程序
; 以下是启动区以外部分的输出
; DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
; RESB 4600
; DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
; RESB 1469432
; 寄存器
; AX accumulator,累加寄存器
; CX counter,计数寄存器
; DX data,数据寄存器
; BX base,基址寄存器
; SP stack pointer,栈指针寄存器
; BP base pointer,基址值住寄存器
; SI source index,源变址寄存器
; DI destination index,目的变址寄存器
; 以上为16位寄存器,X表示扩展,之前的cpu寄存器为8位,寄存器加上E即为32位寄存器,如EAX
; AL——累加寄存器低位(accumulator low)
; CL——计数寄存器低位(counter low)
; DL——数据寄存器低位(data low)
; BL——基址寄存器低位(base low)
; AH——累加寄存器高位(accumulator high)
; CH——计数寄存器高位(counter high)
; DH——数据寄存器高位(data high)
; BH——基址寄存器高位(base high)
; 以上寄存器为8位
; ES——附加段寄存器(extra segment)
; CS——代码段寄存器(code segment)
; SS——栈段寄存器(stack segment)
; DS——数据段寄存器(data segment)
; FS——没有名称(segment part 2)
; GS——没有名称(segment part 3)
; 以上位16位段寄存器
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。