|
【匯編語言程序】在軟盤啟動畫面上用循環顯示」0123456789「 |
一派掌門 二十級 |
先看最終運行效果:
|
一派掌門 二十級 |
複製光盤裏的G:\tolset文件夾到硬盤上,比如D:\tolset。然後複製G:\projects\02_day\helloos4文件夾到剛才的tolset文件夾裏面。進入helloos4文件夾,用記事本打開ipl.nas文件,把裏面的內容全刪了,改成下面的程序:(這個程序是我自己寫的)
ORG 0x7c00 JMP entry DB 0x90
DB "HELLOIPL" DW 512 DB 1
DW 1 DB 2 DW 224 DW 2880 DB 0xf0 DW 9 DW 18 DW 2 DD 0 DD 2880 DB 0, 0, 0x29 DD 0xffffffff DB "HELLO-OS " DB "FAT12 "
RESB 18
; 這是程序開始執行的地方 entry: MOV AX, 0 MOV SS, AX MOV SP, 0x7c00 MOV DS, AX MOV ES, AX MOV DL, 0 ; 把寄存器DL的值設為0
putloop: ; 關於用BIOS顯示字符,請參考書上第38頁 ; 寄存器AL指定要顯示什麼字符 MOV AL, '0' ADD AL, DL ; 要顯示的字符為'0'+DL。比如'0'+4就是'4'
; 以下三行是為了顯示AL中保存的字符 MOV AH, 0x0e ; AH必須為0x0e MOV BX, 15 ; BH = 0, BL = 15,合起來就是BX=15,這個15是指顏色的編號為15 INT 0x10 ; 執行BIOS中的一個函數,該函數的地址是0x10,該函數的作用是顯示一個字符 CMP DL, 9 ; 判斷DL的值是否等於9 JE fin ; 如果等於9,就跳到fin標籤上執行 ADD DL, 1 ; 如果不等於9,那麼就把DL的值加1 JMP putloop ; 然後跳到putloop上執行,顯示下一個字符
; 無限循環 fin: HLT ; CPU休眠,當鼠標或鍵盤有動作時才被喚醒 JMP fin ; 跳回fin標籤
RESB 0x7dfe-$ ; 把啟動區剩下的字節全部寫上0 DB 0x55, 0xaa ; 啟動區標誌,表示軟盤上有啟動程序
|
|
一派掌門 二十級 |
最後,依次雙擊文件夾里的asm.bat,makeimg.bat和run.bat文件,即可運行程序。
其中asm.bat把匯編語言程序編譯為512位元組的ipl.bin文件,這是軟盤的頭512位元組的啟動區。然後用makeimg.bat把該啟動區變成軟盤iso映像文件,最後run.bat啟動虛擬機運行這個軟盤上的啟動程序。
|
|
一派掌門 二十級 |
【程序2】 ORG 0x7c00 JMP entry DB 0x90 DB "HELLOIPL" DW 512 DB 1 DW 1 DB 2 DW 224 DW 2880 DB 0xf0 DW 9 DW 18 DW 2 DD 0 DD 2880 DB 0, 0, 0x29 DD 0xffffffff DB "HELLO-OS " DB "FAT12 " RESB 18 ; 這是程序開始執行的地方 entry: MOV AX, 0 MOV SS, AX MOV SP, 0x7c00 MOV DS, AX MOV ES, AX MOV DL, 0 ; DL的初值為0 ; 準備好顯示字符的所需參數: AH和BX MOV AH, 0x0e MOV BX, 15 putloop: ; 顯示字符DL + '0' MOV AL, DL ADD AL, '0' INT 0x10 ; 顯示逗號 MOV AL, ',' INT 0x10 ; 顯示空格 MOV AL, ' ' INT 0x10 ; 如果DL==9就跳轉到fin,否則DL++並跳轉到putloop CMP DL, 9 JE fin ADD DL, 1 JMP putloop ; 無限循環 fin: HLT JMP fin RESB 0x7dfe-$ DB 0x55, 0xaa 【運行結果】
|
|
一派掌門 二十級 |
由於DL是CPU上的一個寄存器,不是內存上的一個存儲單元,所以這個程序執行起來肯定比C語言快。因為在C語言中定義一個int型的變量的話,其值是存儲在內存中的。
|
|
一派掌門 二十級 |
【程序3】 ORG 0x7c00 JMP entry DB 0x90 DB "HELLOIPL" DW 512 DB 1 DW 1 DB 2 DW 224 DW 2880 DB 0xf0 DW 9 DW 18 DW 2 DD 0 DD 2880 DB 0, 0, 0x29 DD 0xffffffff DB "HELLO-OS " DB "FAT12 " RESB 18 ; 這是程序開始執行的地方 entry: MOV AX, 0 MOV SS, AX MOV SP, 0x7c00 MOV DS, AX MOV ES, AX MOV DL, 0 ; DL的初值為0 ; 準備好顯示字符的所需參數: AH和BX MOV AH, 0x0e MOV BX, 15 putloop: ; 顯示八進制數的第一位 ; AL = DL >> 3 + '0' MOV AL, DL SHR AL, 3 ; 位右移3位 ADD AL, '0' INT 0x10 ; 顯示八進制數的第二位 ; AL = DL & 0x07 MOV AL, DL AND AL, 0x07 ADD AL, '0' INT 0x10 ; 如果DL==63, 則跳轉到fin CMP DL, 63 JE fin ; 否則顯示逗號和空格並使DL的值加1,然後跳回putloop MOV AL, ',' INT 0x10 MOV AL, ' ' INT 0x10 ADD DL, 1 JMP putloop ; 無限循環 fin: HLT JMP fin RESB 0x7dfe-$ DB 0x55, 0xaa 【運行結果】
|
|
一派掌門 二十級 |
昨天下午我試了很久,DIV除法指令在這裏不知為何沒有任何作用,執行後AH和AL的值還是沒變。所以本來想做十進制數0~99的輸出的,結果以失敗告終了。
|
|