1. 程式人生 > >【實戰編程】編寫0號中斷處理程序

【實戰編程】編寫0號中斷處理程序

查看 com col 長度 獲取 pre p s 更改 end

題目:編寫0號中斷處理程序,在除法溢出時,在屏幕中間顯示字符串“hacker by admin!”

之前先補充一個rep movsb的指令知識

movsb和movsw是相反的,都是根據標誌寄存器DF的值選擇正向傳遞還是反向傳遞。

這兩個指令都是把ds:si中的值傳遞到es:di的位置中去

如果df=0時,取正向移動。(inc si和di)

如果df=1時,取反向移動。(dec si和di)

由上可知,只需要改變si和di的值就可以選擇正向還是反向

cld 指令 :使df=0;std 指令 :使df=1.

註:使用movsb或movsw時 正確時候操作是:rep movsb

下面開始正式編程

assume cs:code
data segment db
hacker by admin! data ends code segment start: mov ax,cs mov ds,ax mov si,offset do mov ax,0 mov es,ax mov di,200h mov cx,offset doend - offset do ;獲取中斷程序的長度,好進行復制 cld rep movsb mov word ptr es:[0],200h mov word ptr es:
[2],0h mov dx,0ffffhmov bx,1div bx ;測試除法溢出的代碼 mov ax,4c00h int 21h do: mov ax,data mov ds,ax mov si,0h mov ax,0b800h mov es,ax mov di,0 mov cx,16 s: mov ah,2 ;綠色字體 mov al,ds:[si] mov es:[di],ax inc si inc di inc di loop s mov ax,4c00h int 21h doend:nop code ends end start

上述代碼寫完後,可以執行看看

技術分享

可以說是成功編寫完畢了。

但這裏其實還有個小毛病不知道各位有沒有發現

我的data段數據是放在do子程序的外面!!!

懂8086機制的同學們就知道,每一次程序開啟,所分配的空間都是系統自己給我們的,也就是說

在程序運行期間,data段的數據是存在的。

一旦程序退出了,原本存放在內存中的data數據就立馬會被其他的程序數據覆蓋掉!!

經更改後代碼如下:

assume cs:code

code segment
start:
mov ax,cs
mov ds,ax
mov si,offset do
mov ax,0
mov es,ax
mov di,200h
mov cx,offset doend - offset do
cld
rep movsb
mov word ptr es:[0],200h
mov word ptr es:[2],0h
;mov dx,0ffffh
;mov bx,1
;div bx
mov ax,4c00h
int 21h

do:jmp short dostart
db hacker by admin!‘   ;我們將data中的數據放帶do子程序裏來

dostart: 
mov ax,0
mov ds,ax
mov si,202h
mov ax,0b800h
mov es,ax
mov di,160*8+80    ;取屏幕中間部分
mov cx,16
s:
mov ah,2
mov al,ds:[si]
mov es:[di],ax
inc si
inc di
inc di
loop s
mov ax,4c00h
int 21h
doend:nop

code ends
end start

將data中的數據放在子程序裏來,可以看到,在數據的前面有一個jmp指令

用來跳轉到我們真正的中斷程序中!

在8086匯編中 jmp指令占用2個字節空間,所以我們的si將會在202H處開始復制數據到顯示屏中

下圖是我安裝好程序,再去用debug查看0:0200內存區域 代碼還是在那裏【因為其他合法的程序一般都不會使用 0:200~0:2FF( 0:200h~0:2FFh)的 256個字節的空間】

技術分享

接下來用debug的a指令讓程序手動溢出試試

mov dx,0ffffh
mov bx,1
div bx

技術分享

所以說,只要運行一遍這個程序,在之後無論什麽時候出現除法溢出都會成功顯示該字符串。

【實戰編程】編寫0號中斷處理程序