天天看點

8086鍵盤輸入實驗——《x86彙編語言:從實模式到保護模式》讀書筆記071.BIOS中斷2.鍵盤讀字元并顯示的實驗

1.BIOS中斷

我們可以為所有中斷類型自定義中斷處理過程,包括内部中斷、硬體中斷和軟中斷。

BIOS中斷,又稱BIOS功能調用,主要是為了友善地使用最基本的硬體通路功能。通常,為了區分針對同一硬體的不同功能,使用寄存器AH來指定具體的功能編号。

比如說,以下的指令用于從鍵盤讀取一個按鍵:

mov ah,0x00     ;0功能号對應從鍵盤讀字元
    int 0x16        ;鍵盤服務, int 0x16
                    ; 中斷傳回時,字元的ASCII在AL中      

需要說明的是,BIOS可能會為一些簡單地外圍裝置提供初始化代碼和功能調用代碼,并填寫中斷向量表,但是有一些BIOS中斷是由外部裝置接口自己建立的。

首先,每個外部裝置接口,包括各種闆卡,如網卡、顯示卡、鍵盤接口電路、硬體控制器等,都有自己的隻讀存儲器(ROM),類似于BIOS晶片,這些ROM中提供了它們自己的功能調用例程,以及本裝置的初始化代碼。按照規範,前兩個單元的内容是0x55和0xAA,第三個單元是本ROM中的代碼長度(以512位元組為機關);從第四個單元開始,就是實際的ROM代碼。

其次,我們知道,從記憶體實體位址A0000開始,到FFFFF結束,有相當一部分空間是留給外圍裝置的。如果裝置存在,那麼它自帶的ROM會映射到配置設定給它的位址範圍内。

在計算機啟動期間,BIOS會以2KB為機關搜尋記憶體位址C0000~E0000之間的區域。當它發現某個區域的前兩個位元組是0x55和0xAA時,那意味着該區域有ROM代碼的存在,是有效的。接着,它對該區域做累加和檢查,看結果是否和第三個單元相符。如果相符,就從第四個單元進入。這時候,處理器執行的是硬體自帶的程式指令,這些指令初始化外部裝置的相關寄存器和工作狀态。最後,填寫相關的中斷向量表,使其指向自帶的中斷處理過程。

2.鍵盤讀字元并顯示的實驗

(1)代碼清單

;代碼清單9-2
         ;檔案名:c09_2.asm
         ;檔案說明:用于示範BIOS中斷的使用者程式 
         ;建立日期:2012-3-28 20:35
         
;===============================================================================
SECTION header vstart=0                     ;定義使用者程式頭部段 
    program_length  dd program_end          ;程式總長度[0x00]
    
    ;使用者程式入口點
    code_entry      dw start                ;偏移位址[0x04]
                    dd section.code.start   ;段位址[0x06] 
    
    realloc_tbl_len dw (header_end-realloc_begin)/4
                                            ;段重定位表項個數[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位元組對齊) 
start:
      mov ax,[stack_segment]
      mov ss,ax
      mov sp,ss_pointer
      mov ax,[data_segment]
      mov ds,ax
      
      mov cx,msg_end-message
      mov bx,message
      
 .putc:
      mov ah,0x0e
      mov al,[bx]
      int 0x10
      inc bx
      loop .putc

 .reps:
      mov ah,0x00
      int 0x16
      
      mov ah,0x0e
      mov bl,0x07
      int 0x10

      jmp .reps

;===============================================================================
SECTION data align=16 vstart=0

    message       db 'Hello, friend!',0x0d,0x0a
                  db 'This simple procedure used to demonstrate '
                  db 'the BIOS interrupt.',0x0d,0x0a
                  db 'Please press the keys on the keyboard ->'
    msg_end:
                   
;===============================================================================
SECTION stack align=16 vstart=0
           
                 resb 256
ss_pointer:
 
;===============================================================================
SECTION program_trail
program_end:      

(2)使用BIOS中斷向螢幕寫字元

關于代碼,頭部的部分和SS,DS的初始化自然不用多說,我們已經很熟悉了。

mov cx,msg_end-message
      mov bx,message
      
 .putc:
      mov ah,0x0e
      mov al,[bx]
      int 0x10
      inc bx
      loop .putc      

首先,把重複次數傳入CX,然後讓BX指向要顯示的資訊的首位址。

接下來,我們要利用0x10号中斷的0x0e号功能。

BIOS中斷顯示服務(Video Service——INT 10H)

功能描述:在Teletype模式下顯示字元,具體說就是在螢幕的光标處寫一個字元,并推進光标的位置。

入口參數:

AH=0EH

AL=字元

BH=頁碼

BL=前景色(圖形模式);注意,僅在圖形模式下,設定BL才會改變前景色;在文本模式下,這個參數不起作用(我們的實驗工作在文本模式下)

出口參數:無

(3)使用BIOS中斷從鍵盤讀取字元

.reps:
      mov ah,0x00
      int 0x16
      
      mov ah,0x0e
      mov bl,0x07   ;我覺得這句可以不要
      int 0x10

      jmp .reps      

前面已經說了,0x16号中斷的0x00号子功能是從鍵盤讀字元。

然後,再次利用0x10号中斷的0x0e号功能,把我們從鍵盤輸入的字元顯示出來。

BIOS中斷鍵盤服務(Keyboard Service——INT 16H)

功能描述:從鍵盤讀入字元

入口參數:

AH=00H——讀鍵盤

AH=10H——讀擴充鍵盤(可根據0000:0496H單元的内容判斷:擴充鍵盤是否有效 )

出口參數:

AH=鍵盤的掃描碼

AL=字元的ASCII碼

(4)實驗結果截圖

8086鍵盤輸入實驗——《x86彙編語言:從實模式到保護模式》讀書筆記071.BIOS中斷2.鍵盤讀字元并顯示的實驗

上圖就是啟動Bochs後,再按C之後的畫面。接下來,我們就可以嘗試按鍵,看看會發生什麼

8086鍵盤輸入實驗——《x86彙編語言:從實模式到保護模式》讀書筆記071.BIOS中斷2.鍵盤讀字元并顯示的實驗

下一次,我們就開始探索32位的x86了,你是否很期待呢?

8086鍵盤輸入實驗——《x86彙編語言:從實模式到保護模式》讀書筆記071.BIOS中斷2.鍵盤讀字元并顯示的實驗

繼續閱讀