緒言
0.1 內(nèi)存駐留與中斷
內(nèi)存駐留程序英文叫Terminate and Stay Resident Program,縮寫為TSR.這些程序加載進內(nèi)存,執(zhí)行完后,就駐留在內(nèi)存里,當(dāng)滿足條件時,調(diào)到前臺來執(zhí)行。
內(nèi)存駐留程序的常用形式有:
>諸如Borland 的SideKick彈出式實用程序
>日歷系統(tǒng)
>網(wǎng)絡(luò)服務(wù)器
>通訊程序
>本地的DOS擴展(如CCDOS,UCDOS等中文系統(tǒng)都屬于這個范疇)
>一些可惡的人利用TSR技術(shù)制作很多可惡的病毒程序,幾乎所有的病毒程序都是TSR程序.
就象多任務(wù)系統(tǒng)調(diào)度一個進程有一個調(diào)度程序一樣,在PC中從前臺程序進入到一個TSR,也要有一個調(diào)度者,只是PC操作系統(tǒng)的調(diào)度不稱為調(diào)度程序,而只稱為觸發(fā)機制.觸發(fā)機制調(diào)度TSR執(zhí)行在PC機上黨稱為激活一個TSR.觸發(fā)機制主要有以下幾種:
>硬件中斷:黨用的是鍵盤中斷INT 9H,時鐘中斷INT 8H,通訊中斷INT 14H,磁盤中斷INT 13H等等.
>軟件中斷:黨用的是鍵盤中斷INT 16H,時鐘中斷INT 1CH,DOS中斷INT 21H,等等.
>以上各種的結(jié)合.
從以上的觸發(fā)機制可以看出,TSR和PC機的中斷系統(tǒng)有著密切的關(guān)系.每種激活方式實際上都是與中斷有關(guān)的.常用特殊的擊鍵序列的識別碼是通過截獲INT 9H和INT 16H來實現(xiàn).實際上不管TSR程序的哪一個環(huán)節(jié),都與中斷有著密切的關(guān)系.因此在具體進行TSR和程序設(shè)計之前,先介紹PC中斷系統(tǒng).在此只作簡單說明.
在PC機內(nèi)存的最低端(0000H開始)的1K字節(jié)中,存放著256個指針即常說的中為向量或中斷矢量(Interrupt vertor),每個中斷向量都指向一個子程序,該程序稱為中斷處理程序(Interrup handler).一個中斷向量由四個字節(jié)組成,有一個字是中斷處理程序的偏移量值,后一個字是中斷處理程序的段值.256中斷向量一起稱為中斷向量表.
手式計算中斷向量的首址,可通過以下的公式來求得:
X號中斷向量的首址=0000H:X*4
當(dāng)產(chǎn)生一個中斷時,處理器都按順序執(zhí)行以下步驟:
>在堆棧上壓入處理器的標志(相當(dāng)于指令PUSHF).
>在堆棧上壓入當(dāng)前CS和IP值(相當(dāng)于指令PUSH CS和PUSH IP).
>關(guān)閉中斷(CLI)
>從中斷向量加載的CS和IP,執(zhí)行中斷處理程序.
當(dāng)執(zhí)行完中斷處理程序后,一般用IRET返回,它的作用是:
>從堆棧上取出保存的IP和CS(相當(dāng)于指令POP CS和PUSH CS).
>同時恢復(fù)中斷前的處理器標志(相當(dāng)于指令POPF).
中斷有多種分類,由觸發(fā)的原因和實現(xiàn)的性質(zhì)來分,可分為硬件中斷和軟件中斷,從操作系統(tǒng)分層實現(xiàn)來說,可以分成BIOS中斷,BOS中斷和用戶中斷.
一方面,BIOS和DOS通過中斷系統(tǒng)向用戶提供一個操作系統(tǒng)功能界面.也就是說用戶(一般來說是前臺程序)的功能主要是通過調(diào)用DOS和BIOS的中斷服務(wù)來實現(xiàn)的,具體來說就是通過INT指令來實現(xiàn)的.另一方面,BIOS和DOS由中斷系統(tǒng)所構(gòu)成,BIOS對硬件成為高層的功能,并通過中斷的形式向用戶提供.
如果在當(dāng)前程序執(zhí)行的同時,能將一塊代碼放在內(nèi)存,把中斷向量指向代碼中的子程序,那么在當(dāng)前程序執(zhí)行中產(chǎn)生中斷時,就有可能執(zhí)行不屬于當(dāng)前程序和操作系統(tǒng)的代碼,產(chǎn)生的中斷可能是當(dāng)前程序產(chǎn)生的軟件中斷,也可能是由硬件產(chǎn)生的硬件中斷.這就是單任務(wù)的PC操作系統(tǒng)可能執(zhí)行多于一個進程的簡單說明.
在PC中斷系統(tǒng)中有幾個中斷具有周期性,即INT 8H,INT 1CH和INT 28H.它們或者周期性被執(zhí)行用于時間計時,或者周期性產(chǎn)生用于等待.它們是在實現(xiàn)TSR時進行輪詢觸發(fā)的基礎(chǔ).鍵盤中斷(INT 9H和INT 16H)當(dāng)用戶擊鍵時發(fā)生,利用它們是進行熱鍵處理的基礎(chǔ).串行口通訊也是觸發(fā)的一個重要機制.此外眾多的軟件中斷也是觸發(fā)的媒介.
0.2 DOS的可重入性分析
一個多任務(wù)操作系統(tǒng)之所以能使多個進行并存,是因為操作系統(tǒng)的大部分代碼是可以了重的,對于臨界資源有相應(yīng)的PV操作,使得當(dāng)調(diào)度一個新的進程時,能完整地保存前一個里程的現(xiàn)場,當(dāng)再一次調(diào)度被掛起的進程時能象沒有被中斷一樣繼續(xù)執(zhí)行.
對于PC機來說,代碼的重入性比較弱,對臨界資源沒有PC操作.當(dāng)我們用中斷程序啟動用戶的TSR時,如果只保存標志和寄存器,以及當(dāng)前進程一些信息,那么只保存了當(dāng)前程序的一部分現(xiàn)場,DOS的臨界資源不會自動保存.在進行TSR設(shè)計時,一定要了解PC操作系統(tǒng)的重入性和臨界資源.
重入性總是體現(xiàn)在代碼上,所謂可重入代碼的指這樣的代碼,即該代碼被執(zhí)行時還沒有從中退出,由于某種原因又一次或者多次進入相同的代碼,該代碼每次的執(zhí)行結(jié)果都是正確的,就說該代碼是可重入的.相反,如果結(jié)果不正確,那么就就該代碼是不可重入的.下面是一個可重入的子程序的例子:
Add proc near
cmp DS:word ptr [si],0
je DonotAddTheValue
add ax,DS:word ptr [si]
DonotAddTheValue:
ret
Add endp
上面的例子不管在其中任何一處再一次執(zhí)行該子程序,執(zhí)行結(jié)果不變.為了說明,只舉多種可能性中的一種.
mov ds,0100h ;ds=0100h
mov si,0010h ;si=0010h
mov ax,0001h ;ax,=0001h
call Add
cmp 0100h:word ptr [0010h],0 ;Call Add subroutine
push ds ;Interrupted
push si
push ax
mov ds,0200h ;ds=0200h
mov si,0200h ;si=0020h
mov ax,0003h ;ax=0003h
call Add
cmp 0200h:word ptr [0020h],0 ;0200:0020h=0004h
jne
add ax,0200h:word ptr [0020h] ;ax=0007h
ret ;Return
pop ax ;ax=0001h
pop si ;si=0010h
pop ds ;ds=0100h
iret ;Return to Add subroutine
jne
add ax,0100h:word ptr [0100h] ;ax= 0001h
;0100h:0010h= 0002h
;----------------------------------------
;ax = 0003h
ret
mov bx,ax
0.1 內(nèi)存駐留與中斷
內(nèi)存駐留程序英文叫Terminate and Stay Resident Program,縮寫為TSR.這些程序加載進內(nèi)存,執(zhí)行完后,就駐留在內(nèi)存里,當(dāng)滿足條件時,調(diào)到前臺來執(zhí)行。
內(nèi)存駐留程序的常用形式有:
>諸如Borland 的SideKick彈出式實用程序
>日歷系統(tǒng)
>網(wǎng)絡(luò)服務(wù)器
>通訊程序
>本地的DOS擴展(如CCDOS,UCDOS等中文系統(tǒng)都屬于這個范疇)
>一些可惡的人利用TSR技術(shù)制作很多可惡的病毒程序,幾乎所有的病毒程序都是TSR程序.
就象多任務(wù)系統(tǒng)調(diào)度一個進程有一個調(diào)度程序一樣,在PC中從前臺程序進入到一個TSR,也要有一個調(diào)度者,只是PC操作系統(tǒng)的調(diào)度不稱為調(diào)度程序,而只稱為觸發(fā)機制.觸發(fā)機制調(diào)度TSR執(zhí)行在PC機上黨稱為激活一個TSR.觸發(fā)機制主要有以下幾種:
>硬件中斷:黨用的是鍵盤中斷INT 9H,時鐘中斷INT 8H,通訊中斷INT 14H,磁盤中斷INT 13H等等.
>軟件中斷:黨用的是鍵盤中斷INT 16H,時鐘中斷INT 1CH,DOS中斷INT 21H,等等.
>以上各種的結(jié)合.
從以上的觸發(fā)機制可以看出,TSR和PC機的中斷系統(tǒng)有著密切的關(guān)系.每種激活方式實際上都是與中斷有關(guān)的.常用特殊的擊鍵序列的識別碼是通過截獲INT 9H和INT 16H來實現(xiàn).實際上不管TSR程序的哪一個環(huán)節(jié),都與中斷有著密切的關(guān)系.因此在具體進行TSR和程序設(shè)計之前,先介紹PC中斷系統(tǒng).在此只作簡單說明.
在PC機內(nèi)存的最低端(0000H開始)的1K字節(jié)中,存放著256個指針即常說的中為向量或中斷矢量(Interrupt vertor),每個中斷向量都指向一個子程序,該程序稱為中斷處理程序(Interrup handler).一個中斷向量由四個字節(jié)組成,有一個字是中斷處理程序的偏移量值,后一個字是中斷處理程序的段值.256中斷向量一起稱為中斷向量表.
手式計算中斷向量的首址,可通過以下的公式來求得:
X號中斷向量的首址=0000H:X*4
當(dāng)產(chǎn)生一個中斷時,處理器都按順序執(zhí)行以下步驟:
>在堆棧上壓入處理器的標志(相當(dāng)于指令PUSHF).
>在堆棧上壓入當(dāng)前CS和IP值(相當(dāng)于指令PUSH CS和PUSH IP).
>關(guān)閉中斷(CLI)
>從中斷向量加載的CS和IP,執(zhí)行中斷處理程序.
當(dāng)執(zhí)行完中斷處理程序后,一般用IRET返回,它的作用是:
>從堆棧上取出保存的IP和CS(相當(dāng)于指令POP CS和PUSH CS).
>同時恢復(fù)中斷前的處理器標志(相當(dāng)于指令POPF).
中斷有多種分類,由觸發(fā)的原因和實現(xiàn)的性質(zhì)來分,可分為硬件中斷和軟件中斷,從操作系統(tǒng)分層實現(xiàn)來說,可以分成BIOS中斷,BOS中斷和用戶中斷.
一方面,BIOS和DOS通過中斷系統(tǒng)向用戶提供一個操作系統(tǒng)功能界面.也就是說用戶(一般來說是前臺程序)的功能主要是通過調(diào)用DOS和BIOS的中斷服務(wù)來實現(xiàn)的,具體來說就是通過INT指令來實現(xiàn)的.另一方面,BIOS和DOS由中斷系統(tǒng)所構(gòu)成,BIOS對硬件成為高層的功能,并通過中斷的形式向用戶提供.
如果在當(dāng)前程序執(zhí)行的同時,能將一塊代碼放在內(nèi)存,把中斷向量指向代碼中的子程序,那么在當(dāng)前程序執(zhí)行中產(chǎn)生中斷時,就有可能執(zhí)行不屬于當(dāng)前程序和操作系統(tǒng)的代碼,產(chǎn)生的中斷可能是當(dāng)前程序產(chǎn)生的軟件中斷,也可能是由硬件產(chǎn)生的硬件中斷.這就是單任務(wù)的PC操作系統(tǒng)可能執(zhí)行多于一個進程的簡單說明.
在PC中斷系統(tǒng)中有幾個中斷具有周期性,即INT 8H,INT 1CH和INT 28H.它們或者周期性被執(zhí)行用于時間計時,或者周期性產(chǎn)生用于等待.它們是在實現(xiàn)TSR時進行輪詢觸發(fā)的基礎(chǔ).鍵盤中斷(INT 9H和INT 16H)當(dāng)用戶擊鍵時發(fā)生,利用它們是進行熱鍵處理的基礎(chǔ).串行口通訊也是觸發(fā)的一個重要機制.此外眾多的軟件中斷也是觸發(fā)的媒介.
0.2 DOS的可重入性分析
一個多任務(wù)操作系統(tǒng)之所以能使多個進行并存,是因為操作系統(tǒng)的大部分代碼是可以了重的,對于臨界資源有相應(yīng)的PV操作,使得當(dāng)調(diào)度一個新的進程時,能完整地保存前一個里程的現(xiàn)場,當(dāng)再一次調(diào)度被掛起的進程時能象沒有被中斷一樣繼續(xù)執(zhí)行.
對于PC機來說,代碼的重入性比較弱,對臨界資源沒有PC操作.當(dāng)我們用中斷程序啟動用戶的TSR時,如果只保存標志和寄存器,以及當(dāng)前進程一些信息,那么只保存了當(dāng)前程序的一部分現(xiàn)場,DOS的臨界資源不會自動保存.在進行TSR設(shè)計時,一定要了解PC操作系統(tǒng)的重入性和臨界資源.
重入性總是體現(xiàn)在代碼上,所謂可重入代碼的指這樣的代碼,即該代碼被執(zhí)行時還沒有從中退出,由于某種原因又一次或者多次進入相同的代碼,該代碼每次的執(zhí)行結(jié)果都是正確的,就說該代碼是可重入的.相反,如果結(jié)果不正確,那么就就該代碼是不可重入的.下面是一個可重入的子程序的例子:
Add proc near
cmp DS:word ptr [si],0
je DonotAddTheValue
add ax,DS:word ptr [si]
DonotAddTheValue:
ret
Add endp
上面的例子不管在其中任何一處再一次執(zhí)行該子程序,執(zhí)行結(jié)果不變.為了說明,只舉多種可能性中的一種.
mov ds,0100h ;ds=0100h
mov si,0010h ;si=0010h
mov ax,0001h ;ax,=0001h
call Add
cmp 0100h:word ptr [0010h],0 ;Call Add subroutine
push ds ;Interrupted
push si
push ax
mov ds,0200h ;ds=0200h
mov si,0200h ;si=0020h
mov ax,0003h ;ax=0003h
call Add
cmp 0200h:word ptr [0020h],0 ;0200:0020h=0004h
jne
add ax,0200h:word ptr [0020h] ;ax=0007h
ret ;Return
pop ax ;ax=0001h
pop si ;si=0010h
pop ds ;ds=0100h
iret ;Return to Add subroutine
jne
add ax,0100h:word ptr [0100h] ;ax= 0001h
;0100h:0010h= 0002h
;----------------------------------------
;ax = 0003h
ret
mov bx,ax

