汇编语言十二
assume cs:code,ss:stack stack segment db 128 dup (0) stack ends code segment start: mov ax,cs ;开始安装 0 号中断的中断处理程序 mov ds,ax ;所谓的安装, 就是将do0子程序代码复制到一段内存区域, 这段内存区域是完全安全的 mov si,offset do0 ;设置 ds:si 指向要复制的子程序的起始地址 mov ax,0 mov es,ax mov di,200h ;设置 es:di 指向该中断处理程序在内存中的起始地址 mov cx,offset do0end-offset do0 ;计算要复制的中断处理程序有多长 cld ;设置复制方向为正 rep movsb ;进行代码的赋值 mov word ptr es:[0*4],200h ;将中断处理程序的首地址注册在中断向量表的对应表项中, 将中断例程安装在 0:200h 是由编程人员决定的 mov word ptr es:[0*4+2],0 mov dx,152 ;一个检测程序 mov ax,0 mov cx,2 div cx ;执行后, 发生除法溢出, 从而进行中断相关的工作 # 要注意的是下面的中断处理程序在本程序执行的时候并不会执行 # 只有在发生中断的时候才会执行, 并且执行的也不是这段代码 # 而是执行已经经过上面的代码复制到 0:200h 处的中断处理程序 # 所以下面的这一片只是为了复制而用的 do0:jmp short do0start ;因为下一段代码只是数据的定义, 不是 CPU 能够识别的指令, 所以需要跳过 db 'divide error!' do0start: mov ax,cs ;因为 do0 已经被安装到了 0:200h 处, 所以 cs 中的值应为 0 mov ds,ax mov si,202h ;因为 do0 标号处的指令占有 2 字节, 所以 ds:[202h] 指向字符串的开始位置 mov ax,0b800 mov es,ax mov di,160*12+34*2 ;设置字符串要显示的目的地址(显示缓冲区的一段空间) mov cx,13 ;循环 13 次 dnext: mov al,[si] mov es:[di],al ;移动字符本身 mov es:[di+1],81h ;设置第二个字节, 即字符显示的颜色 inc si ;源字符的偏移量一次增加一个字节 add di,2 ;目的字符的偏移量一次增加两个字节, 因为还有一个颜色属性字节 loop dnext mov ah,4c ;返回 DOS int 21h do0end:nop code ends end start