30天自制操作系统 day 1 写一个可以在没有操作系统的计算机上输出字符串的程序,并在计算机上运行

  • Post author:
  • Post category:其他




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



编写代码时的错误

  1. 两个操作数的指令,操作数与操作数间应该用逗号隔开
  2. 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



运行结果

在这里插入图片描述



版权声明:本文为ld_long原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。