day 1
工具:qemu 模拟器
今日任务
计算机启动后,在屏幕打印一串字符串。
理论
显示字符的原理
把一些机器指令写在第一扇区。通过int 0x10中断,让显卡在屏幕上显示字符。只需要在0x10之前按照规定准备好寄存器,显卡就能正确显示字符。
显卡显示字符的规定
流程
计算机会按照规定的流程自行启动,初始化结束后,执行物理内存0x7c00处的指令。在这一步之前硬件会把磁盘上的第一个扇区(前512字节)装载到0x7c00处。打印字符串的指令和数据,就是写在这里的。
ORG指令
ORG 0x7c00
ORG指令是伪指令,它不会被CPU指令,是知道汇编器把汇编代码编译成机器码的。这条指令告诉汇编器,下面内容的起始地址是0x7c00。这样做的目的是确定标号的具体地址。比如如果有个标号为entry,entry具体是多少地址,会受到ORG的影响。
实现代码
这个代码和书中的不一样,但是能够实现同样的功能。
ORG 0x7c00 ;伪指令,告诉编译器第一条指令的地址是0x7c00,cpu并不执行
MOV SI,data
putloop:
;为显卡中断做参数准备
MOV AL,[SI] ;AL 要打印的字符
CMP AL,0
JE end
MOV AH,0x0e ;操作码,0x0e是打印字符
MOV BL,15 ;颜色码
MOV BH,0 ;规定填0
INT 0x10 ;显卡中断,填充好AL,AH,BL,BH,进行显卡中断将显示一个字符
ADD SI,1
JMP putloop
end:
HLT
JMP end
data:
DB 0x0a ;换行
DB "hello_world!"
DB 0x0a ;换行
DB 0 ;结束符
fill:
RESB 0x7dfe-$
DB 0x55,0xaa
编写代码时的错误
- 两个操作数的指令,操作数与操作数间应该用逗号隔开
- CMP指令比较时,操作数不能是内存。
编译执行
我已经把tolset里的ztool添加到了环境变量,所以我可以在任何地方通过命令行运行那些工具
编译
nask hello_world.asm hello_world.img
把编译结果作为qemu磁盘的第一扇区
copy hello_world.img tolset\z_tools\qemu\fdimage0.bin
运行qemu
make -C tolset\z_tools\qemu