陳鍾誠

Version 1.0

BIOS 與組合語言 (IBM PC)

IBM PC個人電腦 (以下簡PC) 目前使用的是IA32 的處理器,其啟動程式燒錄在 BIOS 當中。當PC啟動時,會進入 BIOS的啟動程式中,BIOS會進行『系統組態的分析』(System Configuration Analysis),以分析CPU型號、記憶體大小、軟、硬碟機的數量與型式、是否安裝浮點運算器等,做為其它動作的重要參考資料。接著進行『開機自我測試』(POST,Power-On Self Test),以測試記憶體、晶片組、CMOS儲存資料、鍵盤和磁碟機等硬體,若有錯則以訊息告知所在。 接著,會載入作業系統,像是 MS.MS DOS, MS.MS Windows, Linux 等。

另外,BIOS當中燒錄有中斷向量與中斷程式,因此、許多的輸出入動作都可以透過呼叫BIOS完成,不需要程式設計人員再撰寫輸出入程式。這對系統的開發人員而言,是較為方便的,但是對學習IA32組合語言的人而言,往往會將BIOS視為一組神奇的函數,反而無法理解輸出入的原理。

PC的BIOS模組,是由中斷向量 (0x000-0x400)、中斷資料區 (0x400-0x470) 與中斷處理函數所形成的,因此,使用像int $0x10 這樣的指令,就可以呼叫第 10 號中斷,在螢幕上輸出字串。這樣的指令其實是讓程式透過中斷向量,跳入中斷處理函數中,真正的輸出入反而是在中斷處理函數中做完了。

BIOS的資料區包含了輸出入的資訊,舉例而言,位移0x1E-0x3D之處存放了鍵盤緩衝區 (Keyboard typeahead buffer),其中存放有一連串的鍵盤掃描碼,等待16號中斷 (int 16h) 進行處理。表格 1 顯示了PC的BIOS資料區中,各記憶體位址所包含的資料。

表格 1. 個人電腦的BIOS資料區

位移說明位移說明
0000-0007COM1-COM4埠位址004A-004B螢幕的欄數
0008-000FLPT1-LPT4埠位址004C-004D視訊緩衝區的長度
0010-0011已安裝的硬體清單004E-004F視訊緩衝區的起點
0012初始化旗標0050-005F游標位址 (8個視訊頁)
0013-0014記憶體的大小(KB)0060游標結束列
0015-0016I/O通道的記憶體0061游標起始列
0017-0018鍵盤的狀態旗標0062目前顯示的視訊頁編號
0019替代鍵的儲存區0063-0064作用中的視訊基底位址
001A-001B鍵盤緩衝區指標(頭)0065CRT模式暫存器
001C-001D鍵盤緩衝區指標(尾)0066彩色圖形介面卡的暫存器
001E-003D鍵盤緩衝區0067-006B卡帶磁帶資料區
003E-0048磁碟資料區006C-0070計時器資料區
0049目前的視訊模式

PC每個BIOS中斷都有特殊的功能,例如10號中斷是控制螢幕的函數、16號中斷可控制鍵盤、17號中斷可控制印表機、1A中斷可取得計時器、1C中斷則是一個每秒會被執行18.2次的時間中斷函數,重新設定該中斷可讓程式乘是每隔1/18.2秒就執行一次。這些中斷,其實就是一組預先燒錄於BIOS中,可以透過中斷程序呼叫的『裝置驅動程式』。表格 2 顯示了PC的中斷表,這些中斷在撰寫 PC 組合語言時,具有重要的功能,因為PC組合語言可透過這些中斷存取周邊裝置,而不是讓程式設計師直接透過記憶體映射的方式存取周邊裝置。

表格 2:個人電腦PC的中斷表

編號說明編號說明
0除法錯誤19啟動程式載入器
1單步追蹤1A本日時間(單位為18.2次/秒)
2不可遮罩中斷1B鍵盤中斷
3中斷點1C使用者計時器中斷
4溢位1D視訊參數
5列印螢幕1E磁碟參數
6無效的運算碼1F繪圖表格
7無法使用處理器擴充20終止程式
8IRQ0計時器中斷(18.2次/秒)21MS-DOS服務
9IRQ1 鍵盤中斷22MS-DOS終止服務
AIRQ2 可程式化中斷控制器23MS-DOS中斷位址
BIRQ3 序列通訊 (COM2)24MS-DOS嚴重錯誤位址
CIRQ4序列通訊 (COM1)25絕對磁碟的讀取 (已棄用)
DIRQ5 固定磁碟26絕對磁碟的寫入 (已棄用)
EIRQ6 磁碟中斷27終止並且常駐 (已棄用)
FIRQ7 平行印表機28-FF保留
10視訊服務 (螢幕)33滑鼠控制
11設備檢查34-3E浮點樹模擬
12記憶體大小3F覆蓋 (Overlay) 管理程式
13軟碟服務40-41固定磁碟的服務
14非同步序列埠服務42-5F保留:特殊用途
15卡帶控制器60-6B可供應用程式使用
16鍵盤服務6C-7F保留:特殊用途
17印表機服務80-F0保留:由 ROM-BASIC 使用
18執行ROM中的BASICF1-FF可供應用程式使用

舉例而言,由於 0x10 號中斷為螢幕的視訊服務,該服務可以用來設定游標位置,將螢幕上下捲動,顯示字元與字串等。因此、組合語言可以透過 int 10h在螢幕上顯示訊息。表格 3 顯示了BIOS第10號中斷的功能與參數設置表。

表格 3. BIOS第10號中斷 – 螢幕銀幕控制的詳細功能

AH功能參數
0設置顯示方式AL=顯示模式(0~13H)
1設置游標類型CH=游標開始行 CL=游標結束行
2設置游標位置BH=頁號;DH/DL =行號/列號
3讀游標位置BH=頁號
5設置當前顯示頁AL=頁號
6螢幕初始化或上卷AL=上卷行數;AL=0全螢幕為空白;BH=捲入行屬性;CH/CL=左上角行號/列號;DH/DL=右上角行號/列號
7螢幕初始化或下卷AL=下卷行數;AL=0全螢幕為空白 BH=捲入行屬性 CH/CL=左上角行號/列號 DH/DL=右上角行號/列號
8讀游標位置的屬性和字元BH=顯示頁號;AH=屬性;AL =字元
9在游標位置顯示字元和屬性BH=顯示頁號;AL =字元 BL=屬性;CX=字元重複次數
A在游標位置僅顯示字元BH=顯示頁號;AL =字元 CX=字元重複次數
E顯示字元(游標前移)AL =字元;BL=前景色
13顯示字串ES:BP=串地址;CX=串長 DH/DL=起始行/列號;BH=頁號 AL =模式;BL=屬性

那麼,要如何利用組合語言呼叫 int 中斷呢?範例 1 展示了一個利用BIOS中10號中斷以輸出 “Hello!” 字串的程式片段,該程式在設定了許多參數屬性後,利用int $0x10 指令呼叫BIOS,然後就會在銀幕上顯示是一個黑底紅字的 Hello! 字串。

範例 1. 利用PC BIOS的10號中斷,輸出Hello!的範例 (AT&T語法)

…
    mov $msg, %ax
    mov %ax,%bp #ES:BP = 串地址
    mov $6,%cx #CX = 串長度
    mov $0x1301,%ax	#AH = 13, AL = 01h
    mov $0x00C,%bx #頁號為0(BH = 0) 黑底紅字(BL = 0Ch,高亮)
    mov $0,%dl
    int $0x10 #10h 號中斷
    ret
msg:.ascii "Hello!"
…