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-0007 COM1-COM4埠位址 004A-004B 螢幕的欄數
0008-000F LPT1-LPT4埠位址 004C-004D 視訊緩衝區的長度
0010-0011 已安裝的硬體清單 004E-004F 視訊緩衝區的起點
0012 初始化旗標 0050-005F 游標位址 (8個視訊頁)
0013-0014 記憶體的大小(KB) 0060 游標結束列
0015-0016 I/O通道的記憶體 0061 游標起始列
0017-0018 鍵盤的狀態旗標 0062 目前顯示的視訊頁編號
0019 替代鍵的儲存區 0063-0064 作用中的視訊基底位址
001A-001B 鍵盤緩衝區指標(頭) 0065 CRT模式暫存器
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 終止程式
8 IRQ0計時器中斷(18.2次/秒) 21 MS-DOS服務
9 IRQ1 鍵盤中斷 22 MS-DOS終止服務
A IRQ2 可程式化中斷控制器 23 MS-DOS中斷位址
B IRQ3 序列通訊 (COM2) 24 MS-DOS嚴重錯誤位址
C IRQ4序列通訊 (COM1) 25 絕對磁碟的讀取 (已棄用)
D IRQ5 固定磁碟 26 絕對磁碟的寫入 (已棄用)
E IRQ6 磁碟中斷 27 終止並且常駐 (已棄用)
F IRQ7 平行印表機 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中的BASIC F1-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!"
…
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License