設置 | 登錄 | 註冊

目前共有7篇帖子。

【匯編語言程序】在軟盤啟動畫面上用循環顯示」0123456789「

1樓 巨大八爪鱼 2016-2-3 17:03
先看最終運行效果:

2樓 巨大八爪鱼 2016-2-3 17:05
複製光盤裏的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 ; 啟動區標誌,表示軟盤上有啟動程序

3樓 巨大八爪鱼 2016-2-3 17:08
最後,依次雙擊文件夾里的asm.bat,makeimg.bat和run.bat文件,即可運行程序。

其中asm.bat把匯編語言程序編譯為512位元組的ipl.bin文件,這是軟盤的頭512位元組的啟動區。然後用makeimg.bat把該啟動區變成軟盤iso映像文件,最後run.bat啟動虛擬機運行這個軟盤上的啟動程序。
4樓 巨大八爪鱼 2016-2-3 17:33
【程序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
【運行結果】

5樓 巨大八爪鱼 2016-2-3 17:39
由於DL是CPU上的一個寄存器,不是內存上的一個存儲單元,所以這個程序執行起來肯定比C語言快。因為在C語言中定義一個int型的變量的話,其值是存儲在內存中的。
6樓 巨大八爪鱼 2016-2-3 19:58
【程序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
【運行結果】

7樓 巨大八爪鱼 2016-2-4 23:08
昨天下午我試了很久,DIV除法指令在這裏不知為何沒有任何作用,執行後AH和AL的值還是沒變。所以本來想做十進制數0~99的輸出的,結果以失敗告終了。

內容轉換:

回覆帖子
內容:
用戶名: 您目前是匿名發表。
驗證碼:
看不清?換一張
©2010-2025 Purasbar Ver3.0 [手機版] [桌面版]
除非另有聲明,本站採用知識共享署名-相同方式共享 3.0 Unported許可協議進行許可。