使用中斷處理程式實現loop功能

2021-10-10 12:33:43 字數 3380 閱讀 4154

思路:

assume cs:code

code segment

start: mov ax, 0b800h

mov es, ax

mov di, 160*12

mov bx, offset s-offset se

mov cx, 80

s: mov byte ptr es:[di], '!'

add di, 2

int 7ch

se: nop

mov ax, 4c00h;

int 21h

code ends

end start

在7ch中斷處理程式中,需要返回到s處來完成迴圈

在跳轉到7ch時,cs和ip入棧,ip存放的正是se的偏移量

bx=s-se,現在我們得到了se的偏移量,只需要加上bx就能得到

s的偏移量了

因此在處理程式中,我們使用下面這段**:

show: push bp

mov bp, sp

dec cx

jcxz showret

add [bp+2], bx

showret: pop bp

iret

分析一下這段**,訪問棧段記憶體,所以要使用bp暫存器

先儲存他的值,然後讓他指向棧頂,現在的棧中儲存的資料是這樣的:

+----+ 每次將cx的值減1,當cx值為0時,恢復bp的值並返回

| bp | 如果cx的值不為0,就修改ip的值,將其加上bx,得到標號s的

+----+ 偏移位址,然後恢復bp的值,執行iret指令,相當於

| ip | pop ip pop cs

+----+ 這樣一來,程式就會執行到s標號處

| cs | 如果add [bp+2], bx沒有被執行,當iret執行完之後

+----+ 就會執行到se處,這時程式也就結束了

|flag|

+----+ 完整的安裝程式:

|····| assume cs:code

+----+

code segment

start: mov ax, cs

mov ds, ax

mov si, offset show

mov ax, 0

mov es, ax

mov di, 200h

mov cx, offset showend-offset show

cldrep 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

show: push bp

mov bp, sp

dec cx

jcxz showret

add [bp+2], bx

showret:pop bp

iret

showend:nop

code ends

end start

t2.asm:  

assume cs:code

code segment

start: mov ax, 0b800h

mov es, ax

mov di, 160*12

mov bx, offset s-offset se

mov cx, 80

s: mov byte ptr es:[di], '!'

mov byte ptr es:[di+1], 02h

add di, 2

int 7ch

se: nop

mov ax, 4c00h;

int 21h

code ends

end start

t1.asm(安裝程式)

assume cs:code

code segment

start: mov ax, cs

mov ds, ax

mov si, offset show

mov ax, 0

mov es, ax

mov di, 200h

mov cx, offset showend-offset show

cldrep 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

show: push bp

mov bp, sp

dec cx

jcxz showret

add [bp+2], bx

showret:pop bp

iret

showend:nop

code ends

end start

執行過程:

先執行t1.exe,安裝中斷程式

再通過debug除錯t2.exe

執行至int 7ch處時如下所示:

可以看出此時的cs 、ip、和棧中的內容,棧中的數值為之前單步中斷儲存的flag、cs、ip等暫存器的值,再執行一步-t,進入中斷服務函式,如下所示

此時棧頂指標為fffa(指向1c),其中076a為儲存的cs,001c為儲存的ip值,繼續執行兩次-t,看到:

sp變為fff8指向(00),bp的值0000入棧後,將sp的值賦值給了bp。繼續多次執行-t後如圖:

棧中儲存的ip值已經被重新賦值為000e(001c+fff2),繼續執行如下:

將棧中的bp、ip、cs、flag暫存器依次出棧,棧頂指標sp變為0000.程式將會跳到s處繼續執行,

至此,完成了第一次迴圈。後面的迴圈呼叫過程類似

Linux中斷處理程式

裸機中斷 1 有統一的入口,去中斷向量表找對應中斷 2 事先要註冊中斷處理程式 3 根據中斷源的編號呼叫中斷處理程式 linux系統中 1 也同樣有統一入口,在irq svc中 拿到產生中斷源的編號 根據中斷號找到相應的irq desc 根據irp desc找到事先註冊好的中斷處理程式去執行 與裸機...

Linux核心實現中斷和中斷處理(一)

核心是怎麼知道應用程式要呼叫系統呼叫的呢?或者說應用程式怎麼通知系統核心自己需要執行乙個系統呼叫,這是通過軟中斷實現的,通過引發乙個異常來促使系統切換到核心態去執行異常處理程式 ps 什麼時候會從使用者態切換到核心態呢?1.中斷 2.陷阱 3.系統呼叫 中斷分為兩種,硬中斷和軟中斷 在許多處理器體系...

使用rlwrap實現SQLplus翻頁功能

rlwrap工具可以解決linux下sqlplus提供瀏覽歷史命令列的功能,和刪除先前輸入錯誤的字母等問題 一 構建rlwap安裝環境 rlwrap依賴於readline,而readline依賴於libtermcap,所以需要先安裝如下幾個包 libtermcap devel readline re...