汇编指令含义
-
ORG ORG指令来源于英文“origin”,意思是“源头、起点”。它会告诉nask,程序要从指定的这个地址开始,也就是要把程序装载到内存中的指定地址。这里指定的地址是0x7c00 。如果没有它,有几个指令就不能被正确地翻译和执行。另外,有了这条指令的话,美元符($)的含义也随之变化,它不再是指输出文件的第几个字节,而是代表将要读入的内存地址。
-
JMP 相当于C语言的goto语句,来源于英文的jump,意思是“跳转”。
-
entry 这是标签的声明,用于指定JMP指令的跳转目的地等。这与C语言很像。entry这个词是“入口”的意思。
-
MOV 赋值 “MOV AX,0”,相当于“AX=0; ”这样一个赋值语句。
-
ADD 加法指令 “ADD SI,1”的话,就是SI=SI+1。
-
CMP 比较指令 “CMP AL,0”,意思就是将AL中的值与0进行比较
-
JE JE是条件跳转指令中之一。所谓条件跳转指令,就是根据比较的结果决定跳转或不跳转。就JE指令而言,如果比较结果相等,则跳转到指定的地址;而如果比较结果不等,则不跳转,继续执行下一条指令。
-
INT INT是软件中断指令。INT的后面是个数字,使用不同的数字可以调用不同的函数。这次我们调用的是0x10(即16)号函数,它的功能是控制显卡。
- 关于书中说的bios网站已经无法打开,可以在这个网站看到bios的指令,BIOS - OSDev 维基,书中所说的0x10命令的解释如图
-
- 关于书中说的bios网站已经无法打开,可以在这个网站看到bios的指令,BIOS - OSDev 维基,书中所说的0x10命令的解释如图
-
HLT HLT是让CPU停止动作的指令,让CPU进入待机状态,避免CPU毫无意义地空转
-
JC “jump if carry”的缩写,意思是如果进位标志(carry flag)是1的话,就跳转。
-
JNC “Jump if not carry”的缩写。也就是说进位标志是0的话就跳转。
-
JAE “Jump if above or equal”的缩写,意思是大于或等于时跳转。
-
JBE “jump if below or equal”的缩写,意思是小于等于则跳转。
-
RET 相当于return
-
寄存器指令
- 十六位寄存器
- AX—accumulator,累加寄存器
- CX—counter,计数寄存器
- DX—data,数据寄存器
- BX—base,基址寄存器
- SP—stack pointer,栈指针寄存器
- BP—base pointer,基址指针寄存器
- SI—source index,源变址寄存器
- DI—destination index,目的变址寄存器
- 八位寄存器
- AL—累加寄存器低位(accumulator low)
- CL—计数寄存器低位(counter low)
- DL—数据寄存器低位(data low)
- BL—基址寄存器低位(base low)
- AH—累加寄存器高位(accumulator high)
- CH—计数寄存器高位(counter high)
- DH—数据寄存器高位(data high)
- BH—基址寄存器高位(base high)
- 三十二位寄存器
- EAX
- ECX
- EDX
- EBX
- ESP
- EBP
- ESI
- EDI
- 段寄存器 均为16位寄存器
- ES—附加段寄存器(extra segment)
- CS—代码段寄存器(code segment)
- SS—栈段寄存器(stack segment)
- DS—数据段寄存器(data segment)
- FS—没有名称(segment part 2)
- GS—没有名称(segment part 3)
- 十六位寄存器
关于书中所说的内存分布地图,可以参考内存映射(x86)- OSDev 维基书中所说的用途,即下图
制作启动区
使用命令nask.exe ipl.nas ipl.bin ipl.lst来创建lst和bin文件
将z_tools目录下面的fdimg0at.tek文件复制到所在目录下
然后使用命令edimg.exe imgin:fdimg0at.tek wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img即可生成正常大小的img镜像文件
这里的fdimg0at.tek是作者特意生成的压缩空白镜像,只有56KB,目的是为了节省空间,也可以使用全部为0的1440KB大小的bin或img文件来作为输入源,效果是一样的。
编写Makefile文件
作者写的命令相当精简,但是因为我本身环境并不严格与书中一致,这里使用自己的makefile,有个需要注意的点是命令前面必须使用tab,而不能是空格,现在很多编辑器会自动将tab转化为空格,如果遇到报错Makefile:3: *** missing separator. Stop.就需要检查一下。
# 命令
build :
nask.exe ipl.nas ipl.bin
img :
edimg.exe imgin:fdimg0at.tek wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img
run :
qemu-system-i386 -drive file=helloos.img,format=raw,if=floppy
另一个更先进的Makefile
# 默认目标,直接输入 make 就会执行这个
default :
$(MAKE) img
# 编译 ipl.nas 生成 ipl.bin
ipl.bin : ipl.nas
nask.exe ipl.nas ipl.bin ipl.lst
# 使用 edimg 将 ipl.bin 注入模板生成 helloos.img
helloos.img : ipl.bin fdimg0at.tek
edimg.exe imgin:fdimg0at.tek wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img
# 命令别名:制作镜像
img :
$(MAKE) helloos.img
# 命令别名:运行 QEMU
run :
$(MAKE) img
qemu-system-i386 -drive file=helloos.img,format=raw,if=floppy
# 清理生成的文件
clean :
-del ipl.bin
-del ipl.lst
-del helloos.img
也是书中所说的完全体版,拥有默认行为,清理功能,自动依赖,自动构建