注明一下,源代码中有很多原作者留的日文注释,我没去一条一条删去,不管就行了
harib00c:
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加一 CMP SI,5 ; 比较SI和5 JAE error ; SI >= 5 跳error MOV AH,0x00 MOV DL,0x00 ; A僪儔僀僽 INT 0x13 ; 僪儔僀僽偺儕僙僢僩 JMP retry next: MOV AX,ES ; 内存后移0x200 ADD AX,0x0020 MOV ES,AX ; ADD ES,0x020 偲偄偆柦椷偑側偄偺偱偙偆偟偰偄傞 ADD CL,1 ; CL偵1傪懌偡 CMP CL,18 ; CL偲18傪斾妑 JBE readloop ; CL <= 18 偩偭偨傜readloop傊
之所以不在INT 0x13中用MOV AL,0x17指定18个扇区,是因为BIOS在读盘时,指定处理的扇区数时有限制,作者这里也没有说清楚,但在Bochs 2.4.5中不能一次指定72个扇区以上。
7220 if ((drive > 1) || (head > 1) || (sector == 0) || 7221 (num_sectors == 0) || (num_sectors > 72)) { 7222 BX_INFO("int13_diskette: read/write/verify: parameter out of range\n"); 7223 SET_AH(1); 7224 set_diskette_ret_status(1); 7225 SET_AL(0); // no sectors read 7226 SET_CF(); // error occurred 7227 return; 7228 }
具体可以看下这个:https://stackoverflow.com/questions/62483420/int-13h-effective-sector-size
Bochs
bochs是X86硬件平台的开源模拟器,完全可以通过软件来给我们提供各种所需的硬件资源。
和bochs类似的虚拟机软件还有我们常用的VMware、Virtuabox,但区别也是明显的。
bochs是完全依靠软件来模拟整个环境的:从启动到重启包括PC的外设键盘、鼠标、磁盘以及网卡等,全部都是由软件来模拟的,而其余软件则不然(部分依赖于硬件)。
现在0x8200~0xa3ff中装载了磁盘的512×17=8704个字节(一个扇区512字节)
harib00d
CYLS EQU 10 ; 相当于C语言的#define CYLS = 10,EQU是equal的缩写,相当于"=" ····· next: MOV AX,ES ; 傾僪儗僗傪0x200恑傔傞 ADD AX,0x0020 MOV ES,AX ; ADD ES,0x020 偲偄偆柦椷偑側偄偺偱偙偆偟偰偄傞 ADD CL,1 ; CL偵1傪懌偡 CMP CL,18 ; CL偲18傪斾妑 JBE readloop ; CL <= 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傊
扇区:C0-H0-S1:柱面0,磁头0,扇区1,柱面cylinder,磁头head,扇区sector
10×2×18×512=184320byte=180KB 十个柱面
非常好的一张图片,说明了软盘的存储结构
软盘保存文件,文件名会写在0x002600处,文件的内容会写在0x004200之后的地方
用make install命令将haribote.nas用nask编译输出为sys文件
我遇到如下报错,但是不影响sys文件的生成
磁盘上0x004200号地址的程序,因为装载到内存中是从0x8000号地址开始的,因此磁盘0x4200处的内容在内存0x8000+0x4200=0xc200处
注意此时引导区的文件差不多就写完了为ipl.nas
http://oswiki.osask.jp/?(AT)BIOS
还是上面那个日文网页
有个问题,为啥是内存的0x0ff0,搜了一下也没有解释,求指教
; haribote.nas文件 ; 因为(磁盘上10个柱面的数据)读完了执行haribote.sys! MOV [0x0ff0],CH ; 将 读取柱面的数量(此时是10)写到内存的0x0FF0,为什么是0x0FF0? JMP 0xc200
make run结果:黑屏
; haribote-os ; TAB=4 ; 有关BOOT_INFO CYLS EQU 0x0ff0 ; 僽乕僩僙僋僞偑愝掕偡傞 LEDS EQU 0x0ff1 VMODE EQU 0x0ff2 ; 怓悢偵娭偡傞忣曬丅壗價僢僩僇儔乕偐丠 SCRNX EQU 0x0ff4 ; 夝憸搙偺X SCRNY EQU 0x0ff6 ; 夝憸搙偺Y VRAM EQU 0x0ff8 ; 僌儔僼傿僢僋僶僢僼傽偺奐巒斣抧 ORG 0xc200 ; 偙偺僾儘僌儔儉偑偳偙偵撉傒崬傑傟傞偺偐 MOV AL,0x13 ; VGA僌儔僼傿僢僋僗丄320x200x8bit僇儔乕 MOV AH,0x00 INT 0x10 MOV BYTE [VMODE],8 ; 记录画面模式,指令中制定了BYTE,则用8个位来存储8这个数值,内存地址为VMODE,即0x0ff2 MOV WORD [SCRNX],320; 一个字来存储 MOV WORD [SCRNY],200 MOV DWORD [VRAM],0x000a0000 ; 双字 ; MOV AH,0x02 INT 0x16 ; keyboard BIOS MOV [LEDS],AL
按键锁定和换档状态获取
INT=0x16
AH= 0x02状态下的AL返回值:
bit0:右移
bit1:左移
bit2:控制
bit3:Alt
bit4:滚动锁定
bit5:数字锁
bit6:大写锁定
bit7:插入模式
(翻译还是Google翻译的准
好家伙,github上有汉化了的,让我看日文看了这么久(—_—) https://github.com/yourtion/30dayMakeOS
不过给出的文件都是一天的最终版,没有一天里逐步改进的过程
添加了亿点点细节
主要加的功能是把.c变为.sys文件
具体内容(如何调用C语言写的程序)作者说后面再讲
WCOFF模式搜不到,但COFF是指通用对象文件格式
; naskfunc.nas文件 ; naskfunc ; TAB=4 [FORMAT "WCOFF"] ; 制作目标文件的模式 [BITS 32] ; 制作32位模式用的机器语言 ; 制作目标文件的信息 [FILE "naskfunc.nas"] ; 源文件名信息 GLOBAL _io_hlt ; 程序中包含的函数名 ; 以下是实际的函数 [SECTION .text] ; 目标文件中写了这些后再写程序 _io_hlt: ; void io_hlt(void); HLT RET
//bootpack.c文件 /* 告诉C编译器,有一个函数在别的文件里 */ void io_hlt(void); /* 是函数声明却不用{},而用;,这表示的意思是: 函数在别的文件中,你自己找一下 */ void HariMain(void) { fin: io_hlt(); /* 执行naskfunc.nas中的_io_hlt函数 */ goto fin; }
c++中一个文件怎么调用另外一个文件里的函数:
前提为,另一个文件中的函数,不能是静态函数,即不能有static修饰。
调用方法,在调用前进行声明,然后直接调用即可。声明方法:
1 直接在调用前,写函数声明:
如调用函数为int func(int a),那么在调用前只需要
int func(int a);
这样声明后,即可使用func。2 将声明写在头文件中。
如在名为func.h的头文件中加入
int func(int a);
然后在调用的源文件中,引用
#include “func.h”即可调用func
此处属于第一种,但是还未使用io_hlt函数
修饰。
调用方法,在调用前进行声明,然后直接调用即可。
声明方法:
1 直接在调用前,写函数声明:
如调用函数为int func(int a),那么在调用前只需要
int func(int a);
这样声明后,即可使用func。2 将声明写在头文件中。
如在名为func.h的头文件中加入
int func(int a);
然后在调用的源文件中,引用
#include “func.h”即可调用func
此处属于第一种,但是还未使用io_hlt函数
话说作者第三天是不是打了鸡血。。。
欢迎一起学习和讨论
欢迎关注个人其他账号:
B站账号:哔哩哔哩 无名-易
Gitee账号:gitee账号
GitHub账号:GitHub