第三天(续)
第三小节
注明一下,源代码中有很多原作者留的日文注释,我没去一条一条删去,不管就行了
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://*.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