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!"
…
Post preview:
Close preview