【實戰編程】編寫0號中斷處理程序
題目:編寫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號中斷處理程序