为了对中断进行探究,学习到这里时我们尝试编写一个do0程序,同时还要编写一个安装程序p247,把do0安装到系统中,替换原有的0号中断例程。教材中已经给出了do0和p247的完整的程序实现。
但是看完教材里的程序后,我想到了一个问题,在教材给出的do0中,我们自己统计出字符数量然后赋值给cx,那么能不能让程序自动计算呢,答案是肯定的
我们先把do0放在一边,在p247中,我们需要统计出do0本身的长度,教材给了我们一种统计do0本身长度的方式,即:
在do0结束之后,加上一个标号do0end,然后就可通过offset do0end-offset do0 来获取到do0本身的长度
那么,我们应该可以用同样的方法,让编译器去统计字符串的长度
实现方法如下:
sb: db "chufayichu!" sbend: nop
然后我们就可以这样给cx赋值:
mov cx,offset sbend-offset sb
完整代码(do0安装程序)如下:
assume ss:stack,cs:code stack segment stack db 256 dup (0) stack ends code segment main: mov ax,cs mov ds,ax mov si,offset do0; ds:si指向源地址 mov ax,0 mov es,ax mov di,200h; 设置es:di指向目的地址 mov cx,offset do0end-offset do0; 设置cx为传输长度 cld; 设置传送方向为正 rep movsb mov word ptr es:[0*4],200h mov word ptr es:[0*4+2],0; 设置中断向量表 mov ax,4c00h int 21h do0: jmp short do0start sb: db "chufayichu!" sbend: nop do0start: mov ax,cs mov ds,ax mov si,202h; 设置ds:si指向字符串 mov ax,0b800h mov es,ax mov di,12*160+36*2; 设置es:di指向显存空间的中间位置 mov cx,offset sbend-offset sb; 设置cx为字符串长度 s: mov al,[si] mov es:[di],al inc si add di,2 loop s mov ax,4c00h int 21h do0end: nop code ends end main
然后我们进行测试,其中“p247_1”是用上述方法改进后的do0安装程序,“shiyan”是一个故意导致除法错误来引发0号中断的程序
扫描二维码关注公众号,回复:
120320 查看本文章
可以看到,在安装do0之前,执行“shiyan”程序会引发系统原有的0号中断,
而在执行p247_1(即安装do0)之后,“shiyan”程序调用了新的0号中断例程,在屏幕中间显示我们自定义的字符串“chufayichu”
也就是说,使用标号与offset配合的方式来统计字符串长度,在中断例程中是可行的