8086汇编(8、自定义中断)

先说明下无符号除法
指令为 DIV
格式:DIV OPRD
如果:OPRD 为单字节即 BL CL
则:AX/OPRD
结果:AL=商,AH=余数
如果:OPRD 为双字节 BX,CX
则:DXAX/OPRD
结果:AX=商,DX=余数
如果除法发生错误会产生0号中断,我们今天要做的就是将0号中断给改了。
我们之前知道80x25为彩色缓冲区,那么我们可以往这个区域直接写字符就能显示在屏幕上。

DATAS SEGMENT
    ;此处输入数据段代码  
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    mov ax,0
    mov bx,1
    mov dx,1
    div bx
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START


我们直接运行上面除法发现程序报错显示在左上角
在这里插入图片描述
我们现在将int0中断的提示信息移动到屏幕中间并显示红底蓝字。代码如下:

DATAS SEGMENT
    ;此处输入数据段代码  
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    call cpy_new_int0    ;自定义中断的函数拷贝到安全区域
    call chang_int0         ;变更中断向量表中中断0所存的入口指针
    mov ax,0
    mov dx,1
    mov bx,1
    div bx						;DXAX/BX 商在AX中,余数在DX中
    
    MOV AH,4CH
    INT 21H
;================================================    
chang_int0:
	mov ax,0                                  
	mov es,ax									;设置数据到哪里去,一个函数指针4个字节
	mov word ptr es:[0*4],7E00H      ;低2个字节给ip
	mov word ptr es:[0*4+2],0           ;高2个字节给cs
	ret 
;================================================    
new_int0:
	jmp newInt0
string:                         ;用于辅助计算数据起始位置,使用OFFSET string-new_int0得到字符串从什么位置开始读取
	db	'divide error',0	    ;结尾0用于辅助判断数据读到什么位置结束
newInt0:
	mov bx,0B800H  		        ;数据写到80x25彩色缓冲区
	mov es,bx
	mov di,160*10+30*2  		;写在缓冲区的起始位置第10行第60个字节开始
	
	mov bx,0					;数据从哪里来
	mov ds,bx
	mov si,OFFSET string-new_int0 +7E00H   ;由于我们的new_int0-new int0_end 代码被复制到了7E00H起始的位置,所以前面计算的偏移量要加上这个值
showStr:	
	mov dl,ds:[si]          ;显示  从si位置读取一个字节
	cmp dl,0				;判断是否读到0如果已读到0则结束未读到0则继续
	je showStrRet	
	mov es:[di],dl			;将读到的字节写给缓冲区的偶数字节
	mov bx,01000001B		
	mov es:[di+1],bx		;设置奇数字节为红底蓝字
	add di,2				;因为缓冲区2个字节表示一个字符,所以加2
	inc si					;读取下一个字节
	jmp showStr		;无条件循环
	
	
showStrRet:	
	MOV AH,4CH
    INT 21H
new_int0_end: nop    ;辅助计算需要被拷贝的代码结尾
;================================================    
cpy_new_int0:				;拷贝代码
	mov bx,cs			;取代码断地址		
	mov ds,bx			;设置数据从代码断来
	mov si,OFFSET new_int0   ;数据起始位置
	
	mov bx,0				;数据复制到0:7E00H的位置
	mov es,bx
	mov di,7E00H
	
	mov cx,OFFSET new_int0_end-new_int0  ;计算复制的总字节数即循环次数
	cld                       ;设置DF=0 ,0表示si di 自增1,DF=1则相反si di自减 1
	rep movsb          ;重复操作,rep指令就是重复将ds[si]的数据搬到es[di]中,知道cx为0
	ret
	    
;================================================
CODES ENDS
    END START

然后我反注释回来,在执行发现结果如下,说明我们已经修改了int0中断为我们自己的程序
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值