特么這個問題困擾了我好久,畢竟是個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
感謝上面兩位作者的貢獻!