汇编INT中断和I/O指令【获取主板时钟】
1. 中斷向量表
????????中斷是一種使CPU掛起正在執行的程序去處理特殊的事件的操作,處理特殊時間的服務程序稱為中斷程序,即處理中斷的程序。
????????為了便于處理,每一種中斷有 一個編號,稱為中斷號,中斷號的取值范圍是0到255,如屬于內部中斷的除法出錯的中斷號是0,屬于外部中斷的鍵盤中斷的中斷號是9。
? ? ? ? 中斷向量是指中斷處理程序的入口地址,相當于執行中斷程序的指針。為了使系統在響應中斷時,CPU能夠快速地轉入對應的中斷程序,用一張表來保持中斷向量,這張表稱為中斷向量表,中斷向量表的每一項也依次編號為0到255。
2. 內部中斷
? ? ? ? 內部中斷是CPU在執行某些指令時產生的中斷,包括:
- 除法出錯中斷
- 單步中斷
- 斷點中斷
- 溢出中斷
- 中斷指令INT n引起的中斷。n的取值是0到255,如INT 10H表示調用BIOS顯示I/O程序,INT 21H表示調用DOS系統功能等。
3. 外部中斷
? ? ? ? 外部中斷是發生在CPU內部某個事件引起的中斷,IA-32 CPU有兩條外部中斷線,INTR和NMI,INTR可屏蔽,NMI不可屏蔽。
? ? ? ? 鼠標鍵盤等外設的中斷請求通過8259A中斷控制器傳給CPU的INTR引線,8259A初始化時規定了8個優先級IRO至IR7,他們對應的中斷號是08H至0FH,IR8至IR15對應的中斷號類型是70H至77H,系統通過調用相應的中斷處理程序實現IO操作。
4.?I/O
? ? ? ??雖然可以通過BIOS的I/O程序實現鍵盤、硬盤等外設的訪問,但是這種方式訪問I/O設備的一個缺點是依賴BIOS。曾經流行的DOS操作系統在BIOS的基礎上實現對外設的訪問,感興趣的朋友可以看看freedos系統的源碼(https://github.com/FDOS/kernel)。
????????計算機的I/O設備(輸入輸出設備,鼠標鍵盤等)是通過一個硬件接口或控制器與CPU相連,在匯編程序中通過一組寄存器或存儲單元實現I/O設備的訪問,通過I/O指令、寄存器和端口地址實現對外部設備的訪問。
? ? ? ? ?I/O輸入指令從一個端口輸入字節、字或者雙字到累加寄存器,端口地址可以直接方式表示也可以間接方式表示,輸入指令的格式為:
IN 累加器,端口地址
? ? ? ? 端口地址采用直接方式表示時長度是8比特,地址的取值范圍是0到FFH,采用間接方式表示時,端口地址的長度是16比特,通過DX寄存器尋址。
????????輸出指令的格式為:
OUT 端口地址,累加器
? ? ? ?通過上述的指令可以看出,通過I/O端口地址實現對輸入輸出設備的訪問,I/O端口地址是端口的編號,通過端口地址可以訪問端口或者存取接口中的寄存器。?
5. 設置光標位置
? ? ? ? 在實地址模式下,使用10H中斷設置光標的位置,設置方法是AH寄存器的值為2,DL和DH設置光標的行和列。
6. 示例
????????這里編寫一個實地址模式下獲取主板CMOS實時時鐘匯編程序,實現系統上電啟動時在屏幕指定位置顯示的時間信息。獲取RTC/CMOS RAM的時間信息,需要用到I/O指令;指定位置輸出信息,需要用到INT中斷指令。
? ? ? RTC/CMOS時鐘的I/O端口地址如下:
- ?秒:? ? ? 00H
- 報警秒:01H
- 分:? ? ? ?02H
- 報警分:03H
- 時:? ? ? ?04H
- 報警時:05H
- 星期:? ?06H
- 日:? ? ? ?07H
- 月:? ? ? ?08H
- 年:? ? ? ?09H
? ? ? ? ?獲取主板CMOS實時時鐘并顯示的匯編代碼如下:
; nasm -fbin xx.asm -o xx.binsegment textorg 7c00h ; dos env should be 100h start:mov ax, csmov ds, axmov es, ax mov ah, 3int 10hmov si, msgmov ax, mlencall ostr .refresh:call gettmcall fmttm mov ah, 3int 10hmov dl, mlenmov si, datamov ax, dlencall ostrmov ax, 40h .wait:mov cx, 0xffffloop $dec axjnz .wait .end:jmp .refreshgettm:mov al, 0out 70h, alin al, 71h mov [buf+5], almov al, 2out 70h, alin al, 71h mov [buf+4], almov al, 4out 70h, alin al, 71h mov [buf+3], almov al, 7out 70h, alin al, 71h mov [buf+2], almov al, 8out 70h, alin al, 71h mov [buf+1], almov al, 9out 70h, alin al, 71hmov [buf], alret; format time str fmttm:mov di, datamov si, bufmov cx, 6 .floop:lodsbmov ah, alsar al, 4add al, 30hand ah, 0fhadd ah, 30hstosw inc diloop .floop ret; output a string ; si: str pointer ; ax: str length ; dx: location ostr:push ax mov bp, sipush cspop esmov al, 1mov ah, 13hmov bl, 00000010bmov bh, 0pop cxint 10hretbuf resb 6 data db "00/00/00 00:00:00" dlen equ $-data msg db "Current date and time: " mlen equ $-msgtimes 510-($-$$) db 0hdb 0x55,0xaa? ? ? ?將編譯后機器碼寫入手動創建的bochs flat虛擬硬盤并運行,如下圖所示:
? ? ? 使用freedos系統編譯運行,如下圖所示:
????????也可以使用物理機器運行,運行效果和bochs一樣。運行方法是將編譯后的bin文件寫入u盤,并從u盤啟動物理機。
總結
以上是生活随笔為你收集整理的汇编INT中断和I/O指令【获取主板时钟】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: uboot 1.1.6 移植8900网卡
- 下一篇: 我同意 三江方士 对 哥德巴赫猜想 的