int指令


int 指令
格式: int n ,n為中斷類型碼
功能:引發中斷過程
1、取中斷類型碼 n;
2、標志寄存器入棧,IF=0,TF=0;
3、CS、IP 入棧;
4、(IP)=(n*4),(CS)=(n*4+2)
assume cs:code
code segment
start:        mov ax , 0b800h
        mov es , ax
        mov bx , 72ch
        mov byte ptr es:[bx] , '!'    ; 輸出顯示區第12行顯示一個字符 !
        mov byte ptr es:[bx+1] , 2
        int 0    ; 調用 0 號中斷
code ends
end start

程序執行到 int 0 就去調用0號中斷,0號中斷的中斷服務程序在前面被改寫了
中斷處理程序簡稱中斷例程




編寫供應用程序調用的中斷例程
編寫、安裝中斷 7ch 的中斷例程,功能:求一 word 型數據的平方
1、編寫實現求平方功能的程序;
2、安裝程序,我們將其安裝在 0:200 處;
3、設置中斷向量表,將程序的入口地址保存在 7ch 表項中,使其成為中斷 7ch 的中斷例程;
編寫、安裝中斷 7ch 的中斷例程,功能:將一個全是字母,以 0 結尾的字符串,轉化為大寫
assume cs:code
code segment
start:        mov ax , cs
        mov ds , ax
        mov si , offset sqr
        mov ax , 0
        mov es , ax
        mov di , 200h
        mov cx , offset sqrend - offset sqr
        cld
        rep movsb

        mov ax , 0
        mov es , ax
        mov word ptr es:[7ch*4] , 200h
        mov word ptr es:[7ch*4+2] , 0

        mov ax , 4c00h
        int 21h

sqr:        mul ax
        iret                    ; 相當於 pop IP  pop CS popf
sqrend:        nop
code ends
end start


assume cs:code
code segment
start:        mov ax , cs
        mov ds , ax
        mov si , offset capital
        mov ax , 0
        mov es , ax
        mov di , 200h
        mov cx , offset capitalend - offset capital
        cld
        rep movsb

        mov ax , 0
        mov es , ax
        mov word ptr es:[7ch*4] , 200h
        mov word ptr es:[7ch*4+2] , 0

        int 7ch

        mov ax , 4c00h    ; 如果中斷程序中有這段程序這里就可以不加,如果中斷程序中是iret,這里就要加上;
        int 21h    ; 不然無法返回dos輸入命令,這里和中斷程序都加上這段也可以


capital:        jmp short change
        db 'conversation' , 0
change:        mov ax , cs
        mov ds , ax
        mov si , 202h
        mov ax , 0b800h
        mov es , ax
        mov di , 7c6h      ; 具體在顯示緩沖區的顯示位置偏移
s:        mov cl , [si]
        mov ch , 0
        jcxz return
        and byte ptr [si] , 11011111b
        mov cl , [si]
        mov es:[di] , cl
        mov byte ptr es:[di+1] , 2
        inc si
        add di , 2
        jmp short s

return:        iret    ;  這里要寫上中斷返回或者 mov ax , 4c00h  int 21h  返回dos,不然執行后程序無法輸入,因為執行完中斷CS:IP接着向下去執行了;
capitalend:        nop

code ends
end start



這段程序重新安裝7ch處的中斷程序,在以后執行7ch中斷的時候執行這段程序

assume cs:code
code segment
start:        mov ax , cs
        mov ds , ax
        mov si , offset capital
        mov ax , 0
        mov es , ax
        mov di , 200h
        mov cx , offset capitalend - offset capital
        cld
        rep movsb

        mov ax , 0
        mov es , ax
        mov word ptr es:[7ch*4] , 200h
        mov word ptr es:[7ch*4+2] , 0

        mov ax , 4c00h  
        int 21h 

capital:        push ds    ; 中斷用到的寄存器,要先進棧保存,保持中斷后的一致性
        push si
change:mov cl , [si]
        mov ch , 0
        jcxz ok
        and byte ptr [si] , 11011111b
        inc si
        jmp short change
ok:        pop si
        pop ds
        iret
capitalend:        nop

code ends
end start
測試代碼

assume cs:code
data segment
        db 'conversation' , 0
data ends

code segment
start:        mov ax , data
        mov ds , ax
        mov si , 0
        int 7ch   ; 執行這個中斷,會把數據段的字符串改成大寫

        mov ax , 4c00h
        int 21h
code ends
end start










對 int 、iret 和棧的深入理解
重寫 7ch 中斷,實現 loop 跳轉 測試代碼
assume cs:code
code segment
start:        mov ax , cs
        mov ds , ax
        mov si , offset lp
        mov ax , 0
        mov es , ax
        mov di , 200h
        mov cx , offset lpend - offset lp
        cld
        rep movsb

        mov ax , 0
        mov es , ax
        mov word ptr es:[7ch*4] , 200h
        mov word ptr es:[7ch*4+2] , 0

        mov ax , 4c00h 
        int 21h

lp:        push bp         ; 下面要用到bp,所以這里先保存進入中斷前的bp
        mov bp , sp      
  ; 不能直接對sp修改,會導致程序崩潰,所以要訪問棧中數據只能用這種方式
        dec cx
        jcxz lpret
        add [bp+2] , bx      ; bp的值是sp的,所以[bp+2]得到的是ss:sp+2,也就是中斷壓棧的ip的值,為int 7ch下一條指令(nop)的位移,+bx ->IP偏移到標號 s ;
; 如果寄存器相對尋址 寄存器是bp的話,段寄存器就是ss
lpret:        pop bp     ; 恢復bp
        iret         ; 中斷返回,恢復CS:IP
lpend:        nop
code ends
end start
assume cs:code
code segment
start:        mov ax , 0b800h
        mov es , ax
        mov di , 160*12
        mov bx , offset s - offset se        ; 這個負偏移中斷要用到來修改ip的值指向標號s:
        mov cx , 80
s:        mov byte ptr es:[di] , '!'    ; 循環打印 ! 
        mov byte ptr es:[di+1] , 2     ; 設置顏色為綠色
        add di , 2
        int 7ch           ; 設置7ch中斷例程序,實現 loop s 功能
se:        nop
        mov ax , 4c00h
        int 21h
code ends
end start


   為了模擬loop,中斷就要能 dec cx  , 如果(cx)≠0,轉到標號s處執行,否則向下執行。這里的bx就是來記錄這個負位移,中斷靠這個實現向上轉移;
   發生中斷的時候,最后進棧的是CS、IP,這個CS就是標號s的段地址,IP就是中斷下一條指令的偏移;可以在中斷例程中修改這個值實現 loop s 的功能。
   中斷程序中,用bp來保存棧頂sp,進棧后+2就得到中斷最后進棧的IP,與bx相加就是s的偏移
 






BIOS 和 DOS 所提供的中斷例程
    系統板的 ROM 中存放這一套程序,稱為 BIOS(基本輸入輸出系統),BIOS 中主要包括以下幾部分內容:
1、硬件系統的檢測和初始化程序;
2、外部中斷和內部中斷的中斷例程;
3、用於對硬件設備進行 I/O 操作的中斷例程;
4、其它和硬件系統相關的中斷例程序;

     操作系統 DOS 也提供了中斷例程,從操作系統的角度來看,DOS 的中斷例程就是操作系統向程序員提供的編程資源。BIOS 和 DOS 在所提供的中斷例程中包含了許多子程序,這些子程序實現了程序員在編程的時候經常需要用到的功能。程序員在編程的時候,可以用 int 指令直接調用 BIOS 和 DOS 提供的中斷例程,來完成某些工作。

     和硬件設備相關的 DOS 中斷例程中,一般都調用了 BIOS 的中斷例程。





BIOS 和 DOS 中斷例程的安裝過程
     
BIOS 和 DOS 提供的中斷例程在裝到內存中的過程:
1、開始后,CPU 一加電,初始化(CS)=0FFFFh,(IP)=0,自動從 FFFF:0 單元開始執行程序。FFFF:0 處有一條跳轉指令,CPU執行該指令后,轉去執行 BIOS 中的硬件系統檢測和初始化程序。
2、初始化程序將建立 BIOS 所支持的中斷向量,即將 BIOS 提供的中斷例程的入口地址登記在中斷向量表中。對於 BIOS 所提供的中斷例程,只需將入口地址登記在中斷向量表中即可,因為它們是固化到 ROM 中的程序,一直在內存中存在。
3、硬件系統檢測和初始化完成后,調用 int 19h 進行操作系統的引導。從此將計算機交由操作系統控制。
4、DOS 啟動后,除完成其他工作外,還將它所提供的中斷例程裝入內存,並建立相應的中斷向量。


我們不可以編程改變 FFFF:0 處的指令,因為這個地址在系統 BIOS 的地址范圍內,這里存放一條跳轉指令,跳到系統 BIOS 中真正的啟動代碼處。
     Shadow RAM也稱為“影子”內存。它是為了提高系統效率而采用的一種專門技術。 Shadow RAM所使用的物理芯片仍然是CMOS DRAM(動態隨機存取存儲器)芯片。Shadow RAM 占據了系統主存的一部分地址空間。其編址范圍為C0000~FFFFF,即為1MB主存中的 768KB~1024KB區域。這個區域通常也稱為內存保留區,用戶程序不能直接訪問。 Shadow RAM的功能是用來存放各種ROM BIOS的內容。或者說Shadow RAM中的內容是ROM BIOS的拷貝。因此也把它稱為ROM Shadow(即Shadow RAM的內容是ROM BIOS的“影 子”)。 在機器上電時,將自動地把系統BIOS、顯示BIOS及其它適配器的BIOS裝載到Shadow RAM 的指定區域中。由於Shadow RAM的物理編址與對應的ROM相同,所以當需要訪問BIOS時, 只需訪問Shadow RAM即可,而不必再訪問ROM。
     通常訪問ROM的時間在200ns左右,而訪問DRAM的時間小於100ns(最新的DRAM芯片訪問時 間為60ns左右或者更小)。
     // 只有安裝了擴展內存(系統配置640KB以上的RAM內存)才能使用影子內存技術;768KB~1024KB區域為影子區






BIOS 中斷例程應用
       int 10h 中斷例程是 BIOS 提供的中斷例程,其中包含多個和 屏幕輸出相關的子程序。一般來說,供程序員調用的中斷例程中往往包含多個子程序,中斷例程內部用傳遞進來的參數決定執行哪一個子程序。BIOS 和 DOS 提供的中斷例程,都用 ah 來傳遞內部子程序的編號。
// int 10h 中斷例程的設置光標位置功能。
mov ah , 2      ; 置光標
mov bh , 0      ; 第0頁
mov dh , 5      ; dh 中放行號
mov dl , 12     ; dl 中放列號
int 10h
10h 號中斷的2號設置光標位置功能不會自動偏移光標,所以必須每次dl+1
// int 10h 中斷例程的光標位置顯示字符功能
mov ah , 9          ; 光標位置開始顯示字符
mov al , 'a'         ; 字符
mov bh , 0         ; 第0頁
mov bl , 7          ; 顏色屬性
mov cx , 3         ;字符重復個數
int 10h
(ah)=2表示調用第10h號中斷例程的2號子程序,功能為設置光標位置,可以提供光標所在行號(80*25字符模式下:0~24)、列號(80*25字符模式下:0~79),和頁號作為參數。

(bh)=0,(dh)=5,(dl)=12,設置光標到第0頁,第5行,第12列
bh中的頁號的含義:內存地址空間中,B8000h~BFFFFh 共32K的空間,為80*25彩色字符模式的顯示緩沖區。一屏的內容在顯示緩沖區中共占 4000 個字節。
顯示緩沖區為8頁,每頁4K,顯示器可以顯示任意一頁的內容,顯示第0頁的內容就是顯示B8000~B8F9F中的4000個字節的內容將出現在顯示器
(ah)=9 表示調用第 10h 號中斷例程的9號子程序,功能為在光標位置顯示字符,可以提供要顯示的字符、顏色屬性、頁號、字符重復個數作為參數。


;編程:在屏幕的第12行40列顯示3個紅底高亮閃爍綠色的'a'
assume cs:code
code segment
        mov ah , 2
        mov bh , 0
        mov dh , 12
        mov dl , 40
        int 10h

        mov ah , 9
        mov al , 'a'
        mov bh , 0
        mov bl , 11001010b    
        mov cx , 3
        int 10h

        mov ax , 4c00h
        int 21h
code ends
end

效果是aaa一直在閃爍,事先設置好光標,中斷執行完后光標轉到下一行,link的l那,可以寫東西覆蓋






DOS 中斷例程應用
       int 21h 中斷例程是 DOS 提供的中斷例程,其中包含了 DOS 提供給程序員在編程時調用的子程序。
int 21h 中斷例程的 4ch 號功能是程序返回功能
mov ah , 4ch     ; 程序返回
mov al , 0      ; 返回值
int 21h

(ah)=4ch 表示調用第 21h 號中斷例程的 4ch 號子程序,功能為程序返回,可以提供返回值作為參數。

int 21h 中斷例程有在光標位置顯示字符串的功能:
ds:dx  指向要顯示的字符串      ; 需要用 '$' 作為結束符
mov ah , 9      ; 功能號9,表示在光標位置顯示字符串
int 21h      

在屏幕中間顯示字符串 "Welcome to masm!"

assume cs:code
data segment
        db 'Welcome to masm!' , '$'     ; 匯編中字符串還是單個字符用"或者'圍起來都一樣
      ; db "Welcome to masm!" , '$'
data ends

code segment
start:        mov ah , 2      ; 設置光標位置
        mov bh , 0
        mov dh , 12
        mov dl , 32
        int 10h

        mov ax , data
        mov ds , ax
        mov dx , 0                   ; 設置待顯示字符串位置,這個中斷中要用dx來存放偏移
        mov ah , 9           ; 功能號9顯示字符串
        ; mov bl , 11001010b     ;21h中不能設置顏色了都
        int 21h

        mov ax , 4c00h      ; 調用4ch號功能,返回值0
        int 21h  
code ends
end start

如果要顯示的字符串較長,它會自動轉到下一行開頭處繼續顯示,如果到達顯示也最后一行,它還能自動上卷一行。






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM