8086键盘输入实验——《x86汇编语言:从实模式到保护模式》读书笔记07
1.BIOS中斷
我們可以為所有中斷類型自定義中斷處理過(guò)程,包括內(nèi)部中斷、硬件中斷和軟中斷。
BIOS中斷,又稱BIOS功能調(diào)用,主要是為了方便地使用最基本的硬件訪問(wèn)功能。通常,為了區(qū)分針對(duì)同一硬件的不同功能,使用寄存器AH來(lái)指定具體的功能編號(hào)。
比如說(shuō),以下的指令用于從鍵盤讀取一個(gè)按鍵:
mov ah,0x00 ;0功能號(hào)對(duì)應(yīng)從鍵盤讀字符 int 0x16 ;鍵盤服務(wù), int 0x16; 中斷返回時(shí),字符的ASCII在AL中需要說(shuō)明的是,BIOS可能會(huì)為一些簡(jiǎn)單地外圍設(shè)備提供初始化代碼和功能調(diào)用代碼,并填寫中斷向量表,但是有一些BIOS中斷是由外部設(shè)備接口自己建立的。
首先,每個(gè)外部設(shè)備接口,包括各種板卡,如網(wǎng)卡、顯卡、鍵盤接口電路、硬件控制器等,都有自己的只讀存儲(chǔ)器(ROM),類似于BIOS芯片,這些ROM中提供了它們自己的功能調(diào)用例程,以及本設(shè)備的初始化代碼。按照規(guī)范,前兩個(gè)單元的內(nèi)容是0x55和0xAA,第三個(gè)單元是本ROM中的代碼長(zhǎng)度(以512字節(jié)為單位);從第四個(gè)單元開(kāi)始,就是實(shí)際的ROM代碼。
其次,我們知道,從內(nèi)存物理地址A0000開(kāi)始,到FFFFF結(jié)束,有相當(dāng)一部分空間是留給外圍設(shè)備的。如果設(shè)備存在,那么它自帶的ROM會(huì)映射到分配給它的地址范圍內(nèi)。
在計(jì)算機(jī)啟動(dòng)期間,BIOS會(huì)以2KB為單位搜索內(nèi)存地址C0000~E0000之間的區(qū)域。當(dāng)它發(fā)現(xiàn)某個(gè)區(qū)域的前兩個(gè)字節(jié)是0x55和0xAA時(shí),那意味著該區(qū)域有ROM代碼的存在,是有效的。接著,它對(duì)該區(qū)域做累加和檢查,看結(jié)果是否和第三個(gè)單元相符。如果相符,就從第四個(gè)單元進(jìn)入。這時(shí)候,處理器執(zhí)行的是硬件自帶的程序指令,這些指令初始化外部設(shè)備的相關(guān)寄存器和工作狀態(tài)。最后,填寫相關(guān)的中斷向量表,使其指向自帶的中斷處理過(guò)程。
2.鍵盤讀字符并顯示的實(shí)驗(yàn)
(1)代碼清單
;代碼清單9-2;文件名:c09_2.asm;文件說(shuō)明:用于演示BIOS中斷的用戶程序 ;創(chuàng)建日期:2012-3-28 20:35;=============================================================================== SECTION header vstart=0 ;定義用戶程序頭部段 program_length dd program_end ;程序總長(zhǎng)度[0x00];用戶程序入口點(diǎn)code_entry dw start ;偏移地址[0x04]dd section.code.start ;段地址[0x06] realloc_tbl_len dw (header_end-realloc_begin)/4;段重定位表項(xiàng)個(gè)數(shù)[0x0a]realloc_begin:;段重定位表 code_segment dd section.code.start ;[0x0c]data_segment dd section.data.start ;[0x14]stack_segment dd section.stack.start ;[0x1c]header_end: ;=============================================================================== SECTION code align=16 vstart=0 ;定義代碼段(16字節(jié)對(duì)齊) start:mov ax,[stack_segment]mov ss,axmov sp,ss_pointermov ax,[data_segment]mov ds,axmov cx,msg_end-messagemov bx,message.putc:mov ah,0x0emov al,[bx]int 0x10inc bxloop .putc.reps:mov ah,0x00int 0x16mov ah,0x0emov bl,0x07int 0x10jmp .reps;=============================================================================== SECTION data align=16 vstart=0message db 'Hello, friend!',0x0d,0x0adb 'This simple procedure used to demonstrate 'db 'the BIOS interrupt.',0x0d,0x0adb 'Please press the keys on the keyboard ->'msg_end:;=============================================================================== SECTION stack align=16 vstart=0resb 256 ss_pointer:;=============================================================================== SECTION program_trail program_end:(2)使用BIOS中斷向屏幕寫字符
關(guān)于代碼,頭部的部分和SS,DS的初始化自然不用多說(shuō),我們已經(jīng)很熟悉了。
mov cx,msg_end-messagemov bx,message.putc:mov ah,0x0emov al,[bx]int 0x10inc bxloop .putc首先,把重復(fù)次數(shù)傳入CX,然后讓BX指向要顯示的信息的首地址。
接下來(lái),我們要利用0x10號(hào)中斷的0x0e號(hào)功能。
BIOS中斷顯示服務(wù)(Video Service——INT 10H)
功能描述:在Teletype模式下顯示字符,具體說(shuō)就是在屏幕的光標(biāo)處寫一個(gè)字符,并推進(jìn)光標(biāo)的位置。
入口參數(shù):
AH=0EH
AL=字符
BH=頁(yè)碼
BL=前景色(圖形模式);注意,僅在圖形模式下,設(shè)置BL才會(huì)改變前景色;在文本模式下,這個(gè)參數(shù)不起作用(我們的實(shí)驗(yàn)工作在文本模式下)
出口參數(shù):無(wú)
(3)使用BIOS中斷從鍵盤讀取字符
.reps:mov ah,0x00int 0x16mov ah,0x0emov bl,0x07 ;我覺(jué)得這句可以不要int 0x10jmp .reps前面已經(jīng)說(shuō)了,0x16號(hào)中斷的0x00號(hào)子功能是從鍵盤讀字符。
然后,再次利用0x10號(hào)中斷的0x0e號(hào)功能,把我們從鍵盤輸入的字符顯示出來(lái)。
BIOS中斷鍵盤服務(wù)(Keyboard Service——INT 16H)
功能描述:從鍵盤讀入字符
入口參數(shù):
AH=00H——讀鍵盤
AH=10H——讀擴(kuò)展鍵盤(可根據(jù)0000:0496H單元的內(nèi)容判斷:擴(kuò)展鍵盤是否有效 )
出口參數(shù):
AH=鍵盤的掃描碼
AL=字符的ASCII碼
(4)實(shí)驗(yàn)結(jié)果截圖
上圖就是啟動(dòng)Bochs后,再按C之后的畫面。接下來(lái),我們就可以嘗試按鍵,看看會(huì)發(fā)生什么
?
下一次,我們就開(kāi)始探索32位的x86了,你是否很期待呢?
總結(jié)
以上是生活随笔為你收集整理的8086键盘输入实验——《x86汇编语言:从实模式到保护模式》读书笔记07的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 百度网盘小诀窍
- 下一篇: 32位x86处理器编程导入——《x86汇