汇编网首页登录博客注册
wubizao的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态
文章收藏

[2007-11-04 19:57] 实验16--多个功能的子程序的中断例程

图片载入中
代码如下:
assume cs:code,ss:stack

stack segment
db 128 dup (0)
stack ends

code segment
    
/*程序setscreen部分*/
setscreen:       jmp short set
    table        dw sub1,sub2,sub3,sub4;将各子程序偏移地址存在table中
      set:       push bx
                   
                 cmp ah,3   ;比较功能号
                 ja sret
                 mov bl,ah
                 mov bh,0
                 add bx,bx ;算出相应子程序的地址入口
 
                 call word ptr table[bx];调用子程序
      sret:      pop bx
                 iret       ;中断结束

/*子程序sub1,功能号0,清屏*/
sub1:        push bx    ;保护现场
             push cx
             push es

             mov bx,0b800h
             mov es,bx
             mov bx,0
             mov cx,2000
sub1s:       mov byte ptr es:[bx],' ' ;传空格字符
             add bx,2
             loop sub1s

             pop es       ;恢复现场
             pop cx
             pop bx
             ret

/*子程序sub2,功能号1,设置前景色*/
sub2:     push bx       ;保护现场
          push cx
          push es
                 
          mov bx,0b800h
          mov es,bx
          mov bx,1       ;改变属性的起点
          mov cx,2000
sub2s:    and byte ptr es:[bx],11111000b ;前景色清0
          or es:[bx],al ;al=00000***,正好or可以改变
          add bx,2
          loop sub2s

          pop es      ;恢复现场
          pop cx
          pop bx
          ret

/*子程序3,功能号2,改变背景色*/
sub3:    push bx       ;保护现场
         push cx 
         push es

         mov cl,4  ;原al=00000***
         shl al,cl ;将al左移4位,变为0***0000
         mov bx,0b800h
         mov es,bx
         mov bx,1
         mov cx,2000
sub3s:   and byte ptr es:[bx],10001111b
         or es:[bx],al ;改变背景色
         add bx,2
         loop sub3s
         
         pop es        ;恢复现场
         pop cx
         pop bx
         ret

/*子程序4,功能号3,向上移动*/
sub4:    push cx     ;保护现场
         push si
         push di
         push es
         push ds

         mov si,0b800h
         mov es,si
         mov ds,si
         mov si,160 ;设置n+1行
         mov di,0   ;设置n行
         cld        ;方向
         mov cx,24

sub4s:   push cx
         mov cx,160
         rep movsb      ;把n+1行的数据传给n行
         pop cx
         loop sub4s

         mov cx,80     ;清最后一行
         mov si,0
sub4s1:  mov byte ptr [160*24+si],' '
         add si,2
         loop sub4s1
            
         pop ds
         pop es
         pop di
         pop si
         pop cx
         ret

        mov ax,4c00h      
        int 21h

setscreenend:     nop     ;至此新中断int 7ch结束

/*安装程序开始*/
start:    mov ax,cs
          mov ds,ax
          mov si,offset setscreen  ;设置si
          mov ax,0
          mov es,ax
          mov di,200h    ;设置di
          mov cx,offset setscreenend-offset setscreen;设置复制int 7ch的长度
          cld
          rep movsb

         mov ax,0
         mov es,ax
         mov word ptr es:[7ch*4],0 ;设置中断向量表
         mov word ptr es:[7ch*4+2],0020h

         mov ah,3    ;测试功能
         mov al,5
         int 7ch     ;调用int 7ch
         
         mov ax,4c00h
         int 21h


code ends
end start

分析:
在本次实验中需要注意一些问题
我想前提至少要把书上给出的各个子程序的写法看懂
1.关于安装程序
关键就在设置中断向量表这快,以前的做法通常是
设置cs=0,ip=0200h
可是到了本实验问题就很大,如若这样,debug时候会错误
因为在题目中
setscreen:       jmp short set
    table        dw sub1,sub2,sub3,sub4
      set:       push bx
                 ............
                 call word ptr table[bx]
table[bx]=所在段地址:[偏移地址+bx]
如果设置cs=0,ip=0200h
安装成功后
那么table[bx]=0000:[偏移地址+bx]
就有可能会指向错误的地方,并未调用你所想调用的sub
所以应该设置成cs=0020h,ip=0000h



2.新的int 7ch在安装程序中的位置
我在程序中是这样的:
assume cs:code,ss:stack

stack segment
db 128 dup (0)
stack ends

code segment

setscreen:       jmp short set ;本指令2个字节
      table      dw sub1,sub2,sub3,sub4
      set:       push bx
                 .........
                 call word ptr table[bx]
我是把setscreen放在code的最前面
为什么?
因为我一开始放在后面遇到了困难
其实还是标号table惹的祸!
在1中,我说table[bx]=所在段地址:[偏移地址+bx]

关键就在这个偏移地址上
在安装程序中,这个偏移地址是相对安装程序而言的  
setscreen:      jmp short set ;本指令2个字节
所以如果安装在code的后面,在start的前面
那么其实call word ptr table[bx]=call [bx+0002h]

现在需要考虑的是安装到0020:0000后会成功调用sub吗?
那就要看能不能取到sub1,sub2,sub3,sub4的地址

安装好后,其实这个call word ptr table[bx]=call [bx+0002h]
中的0002h也被"安装"了,这样在执行call指令的时候,会正确的调用sub子程序

我的错误:一开始把int 7ch写在安装程序start的后面
结果安装好后,查看
call word ptr table[bx]=call [bx+0033h]
根本不可能调用正确的sub地址!

所以说我们应该注意的是相对的逻辑地址要正确,这样才能保证程序功能的实现
评论次数(3)  |  浏览次数(3221)  |  类型(汇编作业) |  收藏此文  | 

[  Wednesday   发表于  2007-11-05 12:06  ]

强,收藏!

[  zysong   发表于  2007-11-05 17:24  ]

不错。

[  wushuai59   发表于  2008-06-02 23:13  ]

谢谢了,这个对我帮助很大,我说我怎么老是出现问题呢,看完你的总结,我明白了。

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码