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 ENDSSTACKS SEGMENT;此处输入堆栈段代码
STACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKS
START:MOV AX,DATASMOV DS,AXmov ax,0mov bx,1mov dx,1div bxMOV AH,4CHINT 21H
CODES ENDSEND START

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

DATAS SEGMENT;此处输入数据段代码  
DATAS ENDSSTACKS SEGMENT;此处输入堆栈段代码
STACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKS
START:MOV AX,DATASMOV DS,AXcall cpy_new_int0    ;自定义中断的函数拷贝到安全区域call chang_int0         ;变更中断向量表中中断0所存的入口指针mov ax,0mov dx,1mov bx,1div bx						;DXAX/BX 商在AX中,余数在DX中MOV AH,4CHINT 21H
;================================================    
chang_int0:mov ax,0                                  mov es,ax									;设置数据到哪里去,一个函数指针4个字节mov word ptr es:[0*4],7E00H      ;低2个字节给ipmov word ptr es:[0*4+2],0           ;高2个字节给csret 
;================================================    
new_int0:jmp newInt0
string:                         ;用于辅助计算数据起始位置,使用OFFSET string-new_int0得到字符串从什么位置开始读取db	'divide error',0	    ;结尾0用于辅助判断数据读到什么位置结束
newInt0:mov bx,0B800H  		        ;数据写到80x25彩色缓冲区mov es,bxmov di,160*10+30*2  		;写在缓冲区的起始位置第10行第60个字节开始mov bx,0					;数据从哪里来mov ds,bxmov 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个字节表示一个字符,所以加2inc si					;读取下一个字节jmp showStr		;无条件循环showStrRet:	MOV AH,4CHINT 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,bxmov di,7E00Hmov cx,OFFSET new_int0_end-new_int0  ;计算复制的总字节数即循环次数cld                       ;设置DF=0 ,0表示si di 自增1,DF=1则相反si di自减 1rep movsb          ;重复操作,rep指令就是重复将ds[si]的数据搬到es[di]中,知道cx为0ret;================================================
CODES ENDSEND START

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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部