编写0号终端的处理程序,使得在除法溢出发生时,在屏幕中间输出字符串"divide error!"
assume cs:code,ss:stack
stack segment stack
db 128 dup(0)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,128
call cpy_new_int0 ;中断安装程序:
call set_new_int0 ;设置中断向量表
mov ax,0
mov dx,1
mov bx,1
div bx
mov ax,4c00h
int 21h
;================cpy_new_int0==============================
;写 0 号中断安装程序,将new_int0_end-new_int0安装在7e00h的位置。
;================cpy_new_int0==============================
cpy_new_int0:
mov bx,cs
mov ds,bx
mov si,OFFSET new_int0 ;设置数据源 ds:[si]
mov bx,0 ;0:7e00h
mov es,bx
mov di,7e00h ;设置复制目的地址 es:[di]
mov cx,OFFSET new_int0_end-OFFSET new_int0 ;开始将数据源放入目的位置
cld ;让df=0 si di 自增
rep movsb ;
ret
;========================new_int0=========================
;divide error 放入 0b800h的位置
new_int0:
jmp newInt0 ; 这个指令, 在编译器编译时,编译成 jmp short ptr 然后 再加上一个nop,一共还是占三个字节
string: db 'divide error',0
newInt0:
mov bx,0
mov ds,bx ;数据来源
mov si,OFFSET string-new_int0 + 7e00h ;这个数据被放在 7e00位置,所以加上7e00h,才能得到偏移
mov bx,0b800h
mov es,bx ;数据目的位置
mov di,160*10 + 20*2
call show_string
mov ax,4c00h
int 21h
show_string:
push dx
push ds
push es
push si
push di
showString: ;将divide error 放入es:[di]中
mov dl,ds:[si]
cmp dl,0 ;单字母移动
je showStringRet
mov es:[di+0],dl
mov byte ptr es:[di+1],01000010B
add di,2
inc si
jmp showString
showStringRet:
pop di
pop si
pop es
pop si
pop di
ret
new_int0_end:
nop
;================cpy_new_int0==============================
;================cpy_new_int0==============================
;========================set_new_int0=========================
; 更改中断向量表,设置CS和IP,CS:n*4+2 IP = n*4
;========================set_new_int0=========================
set_new_int0:
mov bx,0
mov es,bx
mov word ptr es:[0*4],7e00h ;CS段地址
mov word ptr es:[0*4+2],0 ;IP
ret
;========================set_new_int0=========================
; 更改,中断向量表
;========================set_new_int0=========================
code ends
end start