特么这个问题困扰了我好久,毕竟是个OS newbie,还没有汇编的基础。
在前天的加载loader的实验中,老师要求显示字符串,但是给的代码只是显示一个字符。
愚蠢的我实在没办法,最后为了按期完成实验,只能一个个字符地输出,呀真是羞耻。
好了,趁着清明假期,花了几个小时终于弄懂了。
下面进入正题!
前戏是先对boot.asm和loader.asm编译:
nasm -o boot.bin boot.asm
nasm -o loader.bin loader.asm
然后把boot.bin写入软盘a.img:
dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc
然后三连击,把挂载软盘:
最后一个参数是你floppy文件夹的路径,自己随便去创建一个就好,不一定用/mnt里面的
sudo mount -o loop a.img /home/jennings/exp2/floppy/
sudo cp loader.bin /home/jennings/exp2/floppy/ -v
sudo umount /home/jennings/exp2/floppy/
重点来了(敲黑板),
以下是loader.asm的代码:
org 0100h ; 告诉编译器程序加载到 0100h处 mov ax, cs mov ds, ax mov es, ax call DispStr ; 调用显示字符串例程 jmp $ ; 无限循环 DispStr: mov ax, LoaderMessage mov bp, ax ; es:bp = 串地址 mov cx, 31 ; cx = 串长度 mov ax, 01301h ; ah = 13, al = 01h mov bx, 000ch ; 页号为 0(bh = 0) 黑底红字(bl = 0Ch,高亮) mov dh, 0;显示的行号 mov dl, 39;显示的列号 int 10h ; 10h 号中断 ret LoaderMessage: db "This is Zhengjianning‘s loader."
解释程序:
最上面的3个mov语句是让ds,es,cs指向同一个位置,之后调用显示字符串的函数,然后程序无限循环。
这段程序是利用BIOS提供的int 10h中断服务来对屏幕进行绘制
mov bp, ax的作用就是把字符串的地址放到es:bp处(汇编基础不好,暂时不是很懂这里)
cx是设置字符串的长度,自己数自己的字符串多长然后相应修改
ah是设定服务模式,13h的意思是显示字符串al设置光标位置,01h的意思是光标跟随字符串。具体请参见:http://blog.csdn.net/hua19880705/article/details/8125706,这里写得特别详细,感谢作者!
bx用来设置字符串的属性,颜色啊,闪烁啊,背景啊等等。。。
dh是显示字符串的行号(0~24),dl是显示字符串的列号(0~79)
结果截图:
好激动。。。接下来加载内核的实验要显示字符串不用愚蠢地一个个字符输出了。。。/尴尬
参考文章:
http://blog.csdn.net/rockursoul/article/details/3507282
http://blog.csdn.net/hua19880705/article/details/8125706
感谢上面两位作者的贡献!