匯編學(xué)習(xí)記錄13 INT指令

1.INT指令

  • int指令格式為:int n,n為中斷碼的類(lèi)型,功能是引發(fā)對(duì)應(yīng)中斷碼的中斷
  • int指令執(zhí)行的時(shí)候分為四步:
    (1)從中斷向量表中取得n號(hào)中斷所對(duì)應(yīng)的程序入口地址
    (2)將標(biāo)志寄存器入棧,然后設(shè)置TF和IF位的值為0
    (3)CS和IP依次序入棧
    (4)跳轉(zhuǎn)到程序入口地址(將IP設(shè)置為n* 4,將CS設(shè)置為n *4+2)
  • 所以int指令其實(shí)從效果上來(lái)看,跟call指令有些相似,都是保存現(xiàn)場(chǎng),調(diào)用一段程序

2.編寫(xiě)供應(yīng)用程序調(diào)用的中斷程序的方法

(1)實(shí)現(xiàn)中斷程序功能
(2)將中斷程序安裝在0000:0200處(上一講說(shuō)過(guò)中斷向量表的0000:0200~0000:02FF位置一般是空白的)
(3)設(shè)置中斷向量表,使發(fā)生對(duì)應(yīng)中斷的中斷號(hào)對(duì)應(yīng)到編寫(xiě)出來(lái)的中斷程序(一個(gè)表項(xiàng)兩個(gè)字)

注意:
(1)如果想要在中斷程序執(zhí)行完畢以后返回到原來(lái)程序執(zhí)行的位置,可以調(diào)用iret指令返回。(iret指令表示將IP,CS和標(biāo)志寄存器依次出棧后跳轉(zhuǎn))int指令和iret指令的配套使用同,call指令和ret指令配套使用有相似之處.
(2)一般在編寫(xiě)中斷例程和子程序的時(shí)候,我們都會(huì)將程序要用到寄存器先push到棧中保存起來(lái),以免影響主程序的功能

3.用中斷例程完成loop指令的功能(int,iret指令對(duì)應(yīng)棧機(jī)制的深入理解)

示例代碼:

;數(shù)據(jù)傳送示例代碼,調(diào)用中斷7cH

assume cs:code
code segment
start:
  mov ax,0b800H
  mov es,ax
  mov di,160*12 ; 設(shè)置顯存位置

  mov bx,offset s-offset se ; BX寄存器向子程序中傳遞se到s的偏移值
  mov cx,80 ;循環(huán)打印80個(gè)‘!’
S:
  mov byte ptr es:[di],'!'
  add di,2
  int 7cH ; 跳轉(zhuǎn)到中斷號(hào)為7c的中斷處理程序中去,實(shí)現(xiàn)循環(huán)到S
se: nop

  mov ax,4c00H
  int 21H

code ends
end start

; 7cH中斷例程

  push bp ; 此程序?qū)⒁玫絙p,故先保存bp的值
  mov bp,sp
  dec cx ; 實(shí)現(xiàn)loop指令的CX減1
  jcxz lpret ; 
  add [bp+2],bx ; 如果不等于0,則返回到開(kāi)始的地方
lpret:
  pop bp
  iret
 

解釋?zhuān)?/strong>
(1)在執(zhí)行中斷指令int 7cH時(shí),我們將標(biāo)志寄存器,CS和IP都?jí)喝肓藯V校藭r(shí)棧頂存放的應(yīng)該是程序正常執(zhí)行下一條指令的偏移位置。
(2)我們?cè)谥袛嗬讨杏胋p記錄例程開(kāi)始時(shí)棧頂?shù)奈恢?/strong>(其實(shí)這個(gè)程序可以不用bp,但是例程中是有可能修改sp的值的,為嚴(yán)謹(jǐn)我們還是將bp入棧),bx從外面?zhèn)鬟f進(jìn)來(lái)了外程序段的偏移值。
(3)我們看到中斷例程的add那一條指令,其實(shí)就是將棧頂?shù)南乱粋€(gè)元素(也就是IP的值)加上了外程序段偏移值bx,從而實(shí)現(xiàn)了修改IP,實(shí)現(xiàn)loop

4.BIOS和DOS提供的中斷例程

  • BIOS程序(Basic I/O System)放在計(jì)算機(jī)系統(tǒng)板的ROM中,主要包括:
    (1)硬件系統(tǒng)檢測(cè)和初始化程序
    (2)提供外部中斷和內(nèi)部中斷例程
    (3)用于對(duì)硬件設(shè)備進(jìn)行I/O操作的中斷例程
    (4)其他和硬件系統(tǒng)相關(guān)的中斷例程

  • BIOS和DOS均提供了中斷例程,從操作系統(tǒng)角度看,DOS的中斷例程就是操作系統(tǒng)提供給程序員的編程資源。在DOS和硬件設(shè)備相關(guān)的中斷例程中,一般都調(diào)用了BIOS的中斷例程。

  • BIOS和DOS提供的中斷例程的安裝:
    (1)開(kāi)機(jī)的瞬間,CPU一加電,就會(huì)初始化CS=FFFFH,IP=0,自動(dòng)從FFFF:0單元(CPU開(kāi)機(jī)執(zhí)行指令)開(kāi)始執(zhí)行程序,這個(gè)位置有一條跳轉(zhuǎn)指令,會(huì)跳轉(zhuǎn)到BIOS程序中執(zhí)行系統(tǒng)檢測(cè)和初始化指令
    (2)系統(tǒng)檢測(cè)完畢后,初始化程序?qū)?strong>建立BIOS所支持的中斷向量表
    (即將BIOS提供的中斷例程登記在中斷向量表中)
    (3)硬件檢測(cè)和初始化完成以后,執(zhí)行int 19H,進(jìn)行操作系統(tǒng)的引導(dǎo)。從此計(jì)算機(jī)交給操作系統(tǒng)(DOS)控制
    (4)DOS啟動(dòng)完成以后,除了完成其他工作,還會(huì)將DOS本身提供的中斷例程裝入內(nèi)存,并建立相應(yīng)中斷向量。(有的DOS中斷例程是調(diào)用了BIOS的中斷例程)

5.BIOS提供的中斷例程應(yīng)用舉例

  • int 10H 中斷例程是BIOS提供的中斷例程,其中包含了多個(gè)和屏幕輸出相關(guān)的子例程(子例程:一般來(lái)說(shuō)一個(gè)可供程序員調(diào)用的例程中包含了許多個(gè)子程序,稱(chēng)作子例程)。中斷例程的內(nèi)部接受外部傳入的參數(shù),來(lái)決定執(zhí)行哪一個(gè)子程序。在BIOS和DOS提供的中斷例程中,都用ah寄存器來(lái)傳遞內(nèi)部子程序編號(hào)。

代碼舉例:
以下代碼實(shí)現(xiàn)把光標(biāo)設(shè)置到第0頁(yè),第5行,第12列

mov ah,2 ; 調(diào)用2號(hào)子程序,設(shè)置光標(biāo)
mov bh,0 ; 在第0頁(yè)
mov dh,5 ; 行號(hào)為5
mov dl,12 ; 列號(hào)為12
int 10H

(書(shū)中還例舉出當(dāng)ah=9的時(shí)候,10號(hào)中斷可以實(shí)現(xiàn)在光標(biāo)處顯示字符的功能,更多的BIOS中斷可以參考網(wǎng)上資料)

  • int 21H中斷例程是DOS提供的中斷例程,其中包含了許多DOS提供給程序員在編程時(shí)調(diào)用的子程序。如我們經(jīng)常用到的程序返回功能:
mov ax,4c00H
int 21H

這個(gè)語(yǔ)句實(shí)際上是:

mov ah,4cH ;調(diào)用4c號(hào)子程序,功能是程序返回
mov al,0 ; 程序的返回值為0
int 21H

代碼舉例:
以下代碼實(shí)現(xiàn)在光標(biāo)位置顯示字符串。(21H中斷號(hào)的9號(hào)子程序,可以實(shí)現(xiàn)此功能,它將會(huì)輸出ds:dx指向的字符串,字符串以‘$’結(jié)尾)

assume cs:code
data segment
  db 'Welcome to masm!','$'
data ends

code segment
start:
  mov ah,2
  mov bh,0
  mov dh,5
  mov dl,12 ; 設(shè)置光標(biāo)位置
  int 10H

  mov ax,data
  mov ds,ax
  mov dx,0
  mov ah,9
  int 21H ; 調(diào)用光標(biāo)位置顯示字符串

  mov ax,4c00H
  int 21H
code ends
end start

附:實(shí)驗(yàn)說(shuō)明

要求:編寫(xiě)一個(gè)程序分別在屏幕的第2、4、6、8行顯示4句英文詩(shī)(詩(shī)句在數(shù)據(jù)中給出)

實(shí)驗(yàn)參考代碼:

assume cs:code
code segment
S1: db 'Good,better,best,','$'
S2: db 'Never let it rest,','$'
S3: db 'Till good is better,','$'
S4: db 'And better,best.','$'
S:  dw offset S1,offset S2,offset S3,offset S4
row:    db 2,4,6,8

start:  mov ax,cs
    mov ds,ax
    mov bx,offset S
    mov si,offset row

    mov cx,4
ok: mov bh,0 ; 頁(yè)號(hào)
    mov dh,ds:[si] ; 行號(hào)
    mov dl,0 ; 列號(hào)
    mov ah,2 ; 采用10號(hào)中斷的2號(hào)子程序(將光標(biāo)設(shè)置在指定位置)
    int 10H 

    mov dx,ds:[bx] ; 參數(shù)dx傳入21號(hào)中斷的9號(hào)子程序(ds:dx指向要顯示字符串的位置,以‘$’結(jié)尾)
    mov ah,9
    int 21H
    inc si
    add bx,2
    loop ok

    mov ax,4c00H
    int 21H

code ends
end start

實(shí)驗(yàn)截圖:

12345.GIF

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容