王爽汇编中断
中断
中断向量表
共256个表项,每个表项4个字节。共1024个字节。
中断发生时 CPU做了什么事情
1) 得到中断的类型号
2) 标志寄存器的值入栈
3) 设置标志寄存器中的TF和IF为0
4) CS的内容、IP的内容入栈(为了中断处理完成后恢复程序的执行)
5) 根据中断的类型号从中断向量表中找到中断处理程序的入口地址
a) 中断向量表中是一个四字节的数,高位表示段地址,地位表示段内偏移地址
b) 设置CS为高地址,IP为低地址的值
(IP)=中断类型码*4 【字单元】
(CS)=中断类型码*4+2 【字单元】
中断过程中寄存器的入栈顺序是:标志寄存器 、 CS、IP 而iret的出栈顺序是IP、CS、标志寄存器。iret 指令执行后,cpu回到执行中断处理程序前的执行点继续执行程序。
怎样编写中断处理程序
例如:除0中断是0号中断,
1. 中断向量表在内存: 0000:0000~0000:03FF
2. 一般情况下,从0000:0200~0000:02FF的256字节的空间所对应的向量表项是空的。
思路:
l 把do0中断处理程序的内容写到0000:0200开始的地址中(不能超过256个字节)怎么写?
l 然后把中断向量表中0号中断的段地址、IP地址设置成0000、0200。这个好办。
l 为了改写中断向量号的段地址、IP地址,就需要知道中断号,除0是0号,中断处理程序怎么知道中断号的?cpu把中断号传给处理程序吗?怎么传?
怎么写?
最初始的程序设计
0.0(原始社会)
设计一个do0安装程序
assumecs:code
codesegment
start:
设置es:di指向目的地址 ; 0000:0200
设置ds:si指向源地址 ;代码段的地址起始位置
设置cx为传输长度 ;do0程序的字节长度
设置传输的方向为正
rep movsb ;重复传
设置中断向量表
mov ax,4c00H
int 21h
do0:
显示字符串"overflow!jacob"
mov ax,4c00h
int 21h
code ends
end start
1) 源地址怎么得到?
a) 段地址code,偏移量:offset do0;
b) 传送的目的地址: 0:200;
c) 传输的长度; do0部分代码的长度
d) 传输的方向: 正向
0.1(奴隶社会)
assume cs:code
code segment
start:
movax,cs
movds,ax
movsi, offset do0
movax,0
moves,ax
movdi,200h
mov cx,do0部分代码的长度
cld
repmovsb
设置中断向量表
movax,4c00H
int21h
do0:
显示字符串"overflow!jacob"
movax,4c00h
int21h
code ends
end start
怎么得到do0程序的长度呢?
assume cs:code
code segment
start:
movax,cs
movds,ax
movsi, offset do0
movax,0
moves,ax
movdi,200h
movcx, offset do0end-offset do0
cld ;设置传输方向为正
repmovsb
设置中断向量表
movax,4c00H
int21h
do0:
显示字符串"overflow!jacob"
movax,4c00h
int21h
do0end:nop
code ends
end start
0.2(封建社会)
assume cs:code
data segment
db"overflow!"
data ends
code segment
start:
movax,cs
movds,ax
movsi,offset do0
movax,0
moves,ax
movdi,200h
movcx, offset do0end-offset do0
cld
repmovsb
设置中断向量表
movax,4c00h
int21h
do0:
movax,data
movds,ax
movsi,0
movax,0b800h
moves,ax
movdi,12*160+36*2 ;设置es:di指向显存空间的中间位置
movcx,9 ;设置cx的字符串长度
s:mov al,[si]
moves:[di],al
incsi
adddi,2
loops
movax,4c00h
int21h
do0end:nop
code ends
end start
程序12.3
assume cs:code
;data segment
; db"overflow!"
;data ends
code segment
start:
movax,cs
movds,ax
movsi,offset do0
movax,0
moves,ax
movdi,200h
movcx, offset do0end-offset do0
cld
repmovsb
设置中断向量表
movax,4c00h
int21h
do0:jmp short do0start
db 'overflow!'
do0start:
movax,cs
movds,ax
mov si,202h ;设置ds:si指向字符串 202= 200+2(2个字节是jmpshort do0start)
movax,0b800h
moves,ax
movdi,12*160+36*2 ;设置es:di指向显存空间的中间位置
movcx,9 ;设置cx的字符串长度
s:mov al,[si]
moves:[di],al
incsi
adddi,2
loops
movax,4c00h
int21h
do0end:nop
code ends
end start
0.2(资本主义社会)
单步中断
响应中断的特殊情况
0.3(社会主义社会)
assume cs:code
;data segment
; db"overflow!"
;data ends
code segment
start:
movax,cs
movds,ax
movsi,offset do0
movax,0
moves,ax
movdi,200h
movcx, offset do0end-offset do0
cld
repmovsb
;设置中断向量表
movax,0
moves,ax
movword ptr es:[0*4],200H
movword ptr es:[0*4+2],0
movax,4c00h
int21h
do0: jmp short do0start
db'overflow!'
do0start:
movax,cs
movds,ax
movsi,202h ;设置ds:si指向字符串
movax,0b800h
moves,ax
movdi,12*160+36*2 ;设置es:di指向显存空间的中间位置
movcx,9 ;设置cx的字符串长度
s:mov al,[si]
mov ah,11110001B
;moves:[di],al
moves:[di],ax
incsi
adddi,2
loops
movax,4c00h
int21h
do0end:nop
code ends
end start
引发中断的程序
assume cs:code
code segment
start:
movax,1000h
movbh,0h
divbh
code ends
end start