[059][汇编语言]实验 编程 处理0号中断(除法溢出错误)

要做的事情

中断程序入口地址 与 中断程序本身 所在
  • 1、编写可以显示 "overflow" 的中断处理程序 : do0
  • 2、将do0送入内存0000:0200H开始处,即从内存单元0000:0200H开始存放 0号中断处理程序本身
  • 3、将 do0入口地址 0000:0200H存储在 中断向量表 0号表项(内存单元 0000:0000~0000:0003H)

事情做完后得到的东西

从0号表项读取0号中断处理程序的入口地址 从入口地址处开始执行0号中断处理程序.png

程序框架

assume cs:code
    code segment
    start:  do0安装程序
            设置中段向量表
            mov ax,4c00H
            int 21H
    do0:    显示字符串“overflow!”
            mov ax,4c00H
            int 21H
    code ends
    end start

实现 do0 的安装程序

  • 功能:执行do0的安装程序后,会将do0的代码复制到内存0000:0200H处

do0安装代码实现

设置ds:si指向源地址    do0 程序本身所在 【cs:标号do0】
设置es:di指向目的地址   中断向量表的【0000:0200】
设置cx为传输长度
设置传输方向为正
rep movsb


assume cs:code
    code segment
    start:  mov ax,cs
            mov ds,ax
            mov si,offset do0
            
            mov ax,0
            mov es,ax
            mov di,200H
            
            mov cx,offset do0end - offset do0
            cld
            rep movsb
            
            设置中断向量表
            
            mov ax,4c00H
            int 21H
            
        do0:    显示字符串“overflow!"
                mov ax,4c00H
                int 21H
        do0end: nop
                
        code ends
        end start
  • 要使用 rep movsb,必须是ds:si 指向源地址es:di 指向目的地址且结合cx
  • mov si,offset do0 得到标号 do0的偏移地址(原始地址的偏移地址)
  • mov cx,offset do0end - offset do0 计算得到 do0所有指令的字节数(do0代码长度)

实现 do0 中断处理程序本身

  • 功能:在除法溢出发生时,在屏幕上显示字符串“overflow!”

do0程序本身代码实现

assume cs:code
    code segment
    start:  mov ax,cs
            mov ds,ax
            mov si,offset do0
            
            mov ax,0
            mov es,ax
            mov di,200H
            
            mov cx,offset do0end - offset do0
            cld
            rep movsb
            
            设置中断向量表
            
            mov ax,4c00H
            int 21H
            
            
        do0:    jmp short do0Start
                db 'overflow!'
            
        do0Start:   mov ax,cs
                    mov ds,ax
                    mov si,202H
                    
                    
                    mov ax,0B800H
                    mov es,ax
                    mov di,12*160+36*2
                
                    mov cx,9
                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 start
  • "overflow!"字符串 放在 do0程序的开始处
do0:    jmp short do0Start
    db 'overflow!'
  • 设置ds:si指向字符串
mov ax,cs
mov ds,ax
mov si,202H

段地址
  "overflow!" 和 do0的代码处于同一个段中,
  发生除法溢出的时候,do0的段地址就是CS
  所以需要把 ds 设置成 CS

偏移地址
  0000:0200H 处的指令是 jmp short d0start
  这条jmp指令占两个字节,
  所以"overflow!"的偏移地址是 202H

设置中断向量

  • 功能:在中断向量表的0号表项处填入0号中断处理程序的入口地址0000:0020H
mov ax,0
mov es,ax
mov word ptr es:[0*4],200H
mov word ptr es:[0*4+2],0       

完整源码 : do0.asm

完整源码结构.png
assume cs:code
    code segment
    start:  mov ax,cs
            mov ds,ax
            mov si,offset do0
            
            mov ax,0
            mov es,ax
            mov di,200H
            
            mov cx,offset do0end - offset do0
            cld
            rep movsb
            
            
            mov ax,0
            mov es,ax
            mov word ptr es:[0*4],200H
            mov word ptr es:[0*4+2],0
            
            
            
            mov ax,4c00H
            int 21H
            
            
        do0:    jmp short do0Start
                db 'overflow!'
            
        do0Start:   mov ax,cs
                    mov ds,ax
                    mov si,202H
                    
                    
                    mov ax,0B800H
                    mov es,ax
                    mov di,12*160+36*2
                
                    mov ah,02H
                    mov cx,9
                s:  mov al,[si]
                    mov es:[di],al
                    mov es:[di+1],ah
                    inc si
                    add di,2
                    loop s
            
                    mov ax,4c00H
                    int 21H
            do0end: nop
                
        code ends
        end start
  • 方便看结果,对于“overflow”的显示增加了样式:绿色
    mov ah,02H ;绿色
    mov cx,9
s:  mov al,[si]
    mov es:[di],al
    mov es:[di+1],ah ;设置属性

测试程序 : testdo0.asm

assume cs:code
    code segment
    start:  mov ax,0FFFFH
            mov bh,1
            div bh
            
            mov ax,4c00H
            int 21H
                
        code ends
        end start
        

调试测试程序

  • 1、编译、连接、调试,文件 do0.asm
masm do0.asm
link do0.obj
debug do0.exe
使用 debug 【g命令】一步到位执行完全部指令

以看到下面的结果为准:
  (一)在中断处理向量表的0号表项填入入口地址,
       前四个内存单元应该是 00 02 00 00 组成 0000:0200H;
  (二)0号中断处理程序被写入内存0000:0020H开始的地址。
  • 2、编译、连接、调试,文件 testdo0.asm
masm testdo0.asm
link testdo0.obj
debug testdo0.exe
使用debug【u命令】查看 mov ax,4c00H所在内存单元的偏移地址X
使用debug【g命令】 g X 直接跳转到这个地址就可以看输出结果


以看到下面的结果为准:
  (一)在运行testdo0.exe 率先查看中断处理向量表的状态,
  要求入口地址以及处理程序都被正确填写了;
  (二)本程序中的 mov ax,4C00H 语句所在内存单元偏移地址是 0007H,
  因此使用的【G命令】是 g 7 (如图);
  (三)屏幕上出现绿色的字符串 “overflow!” 。

调试过程图解

  • 工具与源码文件在同一个目录层次
0、文件结构,同一文件目录下 编译连接调试工具 与 自己编写的源码文件.png
1 安装do0程序 0号中断处理程序.png
2 调试测试程序 此时内存已经安装好了0号中断处理程序.png
3、运行测试程序 用g命令直接跳到 mov ax 4c00H 处 显示overflow.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,678评论 25 708
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,259评论 4 61
  • 简书连载风云录蔷薇小说目录择一世长安专题择一世长安【目录】 文丨蔷薇下的阳光 上一章 《第三十九章:首战告捷》 前...
    蔷薇下的阳光阅读 648评论 1 10
  • 03102 李佑平 《跑跑镇》,一本创意作品,物与物的碰撞,出现一个新的事物,很有意思。他可以让孩子们将两...
    李佑平阅读 623评论 0 0