02 三十天自制操作系统第二天

23 阅读1分钟

汇编指令含义

  • 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命令的解释如图
      • image.png
  • 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 维基书中所说的用途,即下图

image.png

制作启动区

使用命令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

也是书中所说的完全体版,拥有默认行为,清理功能,自动依赖,自动构建