这里,我们直接采用自己windows电脑自带的文本编辑器即可以完成制作要求
下面先是对昨天使用的helloos.nas文件内容进行详细解释
; hello-os ; TAB=4 ; 标准FAT12格式软盘专用的代码 Stand FAT12 format floppy code DB 0xeb, 0x4e, 0x90 DB "HELLOIPL" ; 启动扇区名称(8字节) DW 512 ; 每个扇区(sector)大小(必须512字节) DB 1 ; 簇(cluster)大小(必须为1个扇区) DW 1 ; FAT起始位置(一般为第一个扇区) DB 2 ; FAT个数(必须为2) DW 224 ; 根目录大小(一般为224项) DW 2880 ; 该磁盘大小(必须为2880扇区1440*1024/512) DB 0xf0 ; 磁盘类型(必须为0xf0) DW 9 ; FAT的长度(必须是9扇区) DW 18 ; 一个磁道(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字节 ; 程序主体 DB 0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c DB 0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a DB 0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09 DB 0xb4, 0x0e, 0xbb, 0x0f, 0x00, 0xcd, 0x10, 0xeb DB 0xee, 0xf4, 0xeb, 0xfd ; 信息显示部分 DB 0x0a, 0x0a ; 换行两次 DB "hello, world" DB 0x0a ; 换行 DB 0 RESB 0x1fe-$ ; 填写0x00直到0x001fe DB 0x55, 0xaa ; 启动扇区以外部分输出 DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 RESB 4600 DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 RESB 1469432
这一个是无条件跳转指令,与有条件跳转指令相对
下面是涵盖汇编语言大部分的MOV指令,非常重要!!
要明白这个指令之前,先需要了解计算机内部寄存器的发展过程:
首先是8位寄存器,有一下几个
在此基础上,每一个寄存器复制一份,两两对应拼接在一起,形成16位寄存器组
这里,以存放一个十六进制数为例:
应当指出的是:上图中说法有误,不同计算机存储数据的方式不同,有大端和小端之分。
接下来,再次将16位寄存器两两拼接,形成32位
接下来,介绍段地址寄存器存在的必要性:
通常我们的电脑存储空间非常大,几百兆甚至几个G,如果要依次进行寻址,那么将会非常耗时间,而且,可能该地址的位数将会很长,超过寄存器32位的限制,这将会很麻烦,段地址寄存器的作用就是将存储空间分为许多大段,而每一段内进行寻址就方便多了,只需要采用段基址加段内地址即可定位
寄存器就介绍完了。
汇编语言的特点:
MOV指令最基本语言有以下两种:
这一种,表示:AL和SI均为寄存器的名称(而且位数相同为8位,不相同,不能执行该指令,强行执行,导致溢出等错误),代表将SI中存储的内容复制到AL中,如果,AL和SI中原先存在内容,AL将会被覆盖,而SI中内容保持不变。
这一种,表示:将会以SI寄存器中存储的内容(数字)解析为一个地址,按照这个地址找到相应的存储单元,将该存储单元的内容复制到AL寄存器中。
标准的MOV指令格式还会加上byte/word/double来限制复制的内容的位数。
接下来是BIOS程序:
采用以上指令进行改写helloos.nas
; hello-os ; TAB=4 ORG 0x7c00 ; 指明程序装载地址 ; 标准FAT12格式软盘专用的代码 Stand FAT12 format floppy code JMP entry DB 0x90 DB "HELLOIPL" ; 启动扇区名称(8字节) DW 512 ; 每个扇区(sector)大小(必须512字节) DB 1 ; 簇(cluster)大小(必须为1个扇区) DW 1 ; FAT起始位置(一般为第一个扇区) DB 2 ; FAT个数(必须为2) DW 224 ; 根目录大小(一般为224项) DW 2880 ; 该磁盘大小(必须为2880扇区1440*1024/512) DB 0xf0 ; 磁盘类型(必须为0xf0) DW 9 ; FAT的长度(必??9扇区) DW 18 ; 一个磁道(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 SI,msg putloop: MOV AL,[SI] ADD SI,1 ; 给SI加1 CMP AL,0 JE fin MOV AH,0x0e ; 显示一个文字 MOV BX,15 ; 指定字符颜色 INT 0x10 ; 调用显卡BIOS JMP putloop fin: HLT ; 让CPU停止,等待指令 JMP fin ; 无限循环 msg: DB 0x0a, 0x0a ; 换行两次 DB "hello, world" DB 0x0a ; 换行 DB 0 RESB 0x7dfe-$ ; 填写0x00直到0x001fe DB 0x55, 0xaa
这里为了方便大家使用。直接将所有命令集成到一块了,只需运行make run命令即可完成所有任务
运行结果
# 默认动作,直接执行不带参数的make,将会制作.img文件 default : ../z_tools/make.exe img # 镜像文件生成,如果要制作文件ipl.bin,就先要检查一下ipl.nas和Makefile两个文件是否准备好了 ipl.bin : ipl.nas Makefile ../z_tools/nask.exe ipl.nas ipl.bin ipl.lst helloos.img : ipl.bin Makefile ../z_tools/edimg.exe imgin:../z_tools/fdimg0at.tek \ wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img # 其他指令 asm : ../z_tools/make.exe -r ipl.bin img : ../z_tools/make.exe -r helloos.img run : ../z_tools/make.exe img copy helloos.img ..\z_tools\qemu\fdimage0.bin ../z_tools/make.exe -C ../z_tools/qemu install : ../z_tools/make.exe img ../z_tools/imgtol.com w a: helloos.img #删除最终结果(这里是helloos.img)以外的所有中间生成文件,清理磁盘 clean : -del ipl.bin -del ipl.lst #把源程序以外的文件全部删除干净 src_only : ../z_tools/make.exe clean -del helloos.img
上段代码中已经做了详细注释