. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->使用BIOS进行键盘输入和磁盘读写
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  关于课程设计二中第3显示时钟:新安装9号中断问题自动执行问题  [待解决] 回复[ 1次 ]   点击[ 466次 ]  
p541938340
[帖 主]   [ 发表时间:2010-03-05 13:04 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:0
注册日期:2009-09-08 11:48
课程设计二从2月27号就开始进行了,在第4设置时钟出现新中断的问题;
本程序思路:
1.安装任务程序到软盘
2.选择4进入显示时间
   (1)清屏
   (2)更改9号中断入口地址
   (3)读取时间并循环显示
 在按F1后产生9号中断,执行新安装的9号中断

具体问题:在当初第3显示时间模块中,为了按f1和ESC产生的事件,设置了新9号中断,测试时候发现
       没有问题,所以在第4的设置时间模块,我在第3显示时间的基础上修改新中断以达到设置时间,
       但就出错了,起初并不怀疑新中断问题,但经大量(几天了)排错,我将第3的中断(以下的新中
       断)中加入显示字符功能测试了下,发现按4进入显示时间后立刻就把该字符串显示出来,说明进
     入后不经过按键盘就引发了一次新中断,真令人困惑,几天寝食不安了,望高手们能帮帮我!

assume cs:codesg

codesg segment
;;;;;;;;;将任务程序安装到软盘;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;软盘第一扇区负责将安装在第二扇区始的任务程序引导到0:700h内存中,然
;;跳到0:7e00h处执行任务程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:         push cs
                 pop es
                 mov bx,offset lead
                   ;写到一扇区
                  mov dl,0
                  mov dh,0
                  mov ch,0
                  mov cl,1   ;第N扇区
                  mov al,1
                  mov ah,3
                  int 13h
                   
                 push cs
                 pop es
                 mov bx,offset boot
                   ;写到二扇区始
                  mov dl,0
                  mov dh,0
                  mov ch,0
                  mov cl,2   ;第N扇区
                  mov al,2
                  mov ah,3
                  int 13h

       mov ax,4c00h
       int 21h
;;;;;;;;;;;;;;;第一扇区的引导程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lead:           mov ax,0
                  mov es,ax
                  mov bx,7e00h ;es:bx指向   这里bx取决于主程序的长度(错误,不管这个读取程序多短,                                        
                                        ;系统都是将第一扇区全部读至0:7c00h处,所以任务程序放0:7e00h,其实
                                        ;也可以根据主程序长度,只要不覆盖到读取它的程序就可以了
                  mov dl,0
                  mov dh,0
                  mov ch,0
                  mov cl,2   ;读第几扇区
                  mov al,2   ;读取扇区数
                  mov ah,2
                  int 13h
                  
                  jmp bx     ;以上程序18字节
leadend:  nop
;;;;;;;;;;;;;;;;;;任务程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
boot:        jmp  showmenu  ;2字节+7e00h  (这里去掉short错误,因为用short才使这条指令2字节)

        s1    db '1)  reset pc    ',0
               db '2)  start system',0
               db '3)  clock       ',0
       s4     db '4)  set clock   ',0
 lenght equ $-s4

 showmenu:  
                   ;以下为显示四行功能选择字符串
                       push cs
                       pop es    
                       mov bx,0bh
                       mov dx,0505h
                       mov bp,offset s1-offset boot+7e00h
                       mov ax,1301h
                       mov cx,4
          shows:   push cx
                       mov cx,lenght
                       int 10h
                       inc dh
                       add bp,cx
                       pop cx
                       loop shows
;;;;;;;;;;;;;;;;;;;选择1-4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;我为了调试只设置4进入;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
       choose:    mov ah,0
                       int 16h

                       cmp al,'4'
                       je key4    ;进入四事件
                       jmp choose
;;;;;;;;;;;;;;;;;key4事件(这原本是第3显示时间的);;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
          key4:      jmp short key4main

       key4s1    db '2000/00/00 00:00:00',0 ;定制格式
       key4s2:    db 9,8,7,4,2,0   
       key4s3:    dw 0,0  ;保存原int9中断向量地址
  key4main:     call clearscreen   ;清屏
                      call inttable  ;调用 设置9号中断向量表

     key4hms:   call key4readtime  ;调用读取时间
                      ;以下为显示
                      push cs
                      pop es    
                      mov bx,0bh
                      mov dx,0505h
                      mov bp,offset key4s1-offset boot+7e00h
                      mov ax,1301h
                      mov cx,19
                      int 10h
                    
                    
                    call delay
                    jmp key4hms   ;循环读取显示以达到动态显示时间

;;;;;;;;;;;;;;;;;;;设置9号中断向量表;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   inttable:     push bx              

                    mov bx,offset key4s3-offset boot+7e00h
                    push cs:[9*4]        ;这里CS恰好是0
                    pop cs:[bx]
                    push cs:[9*4+2]
                    pop cs:[bx+2]          ;将原来的int 9中断例程的入口地址保存

                    cli
                    mov bx,offset int9-offset boot+7e00h  ;ip
                    push bx
                    pop cs:[9*4]
                    mov word ptr cs:[9*4+2],0  ;在中断向量表中设置新的int9中断例程的入口地址
                    sti
                    
                    pop bx
                    ret
;====以下为新的int9中断例程==========================
int9:      push ax
             push bx
             push cx
             push es


;;;;;;;;以下显示为了测试,事实证明选择4进入显示时间后,立刻显示以下代码作用的字符
;;;;;;;;说明按4进入显示时间后不经过按键就发生9号中断,执行了以下新中断的代码
;;;;;;;;真是令人费解!
            ;以下为显示
                      push cs
                      pop es    
                      mov bx,0ch
                      mov dx,0c1fh
                      mov bp,offset key4s1-offset boot+7e00h
                      mov ax,1301h
                      mov cx,19
                      int 10h
;;;;;;;;;下面为F1变颜色的处理模块;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
             in al,60h

             mov bx,offset key4s3-offset boot+7e00h
                    pushf
                    call dword ptr cs:[bx]    ;调用 原int9h


             cmp al,3bh     ;F1的扫描码为3bh
             jne int9ret

             mov ax,0b800h
             mov es,ax
             mov bx,1
             mov cx,2000
  s:         inc byte ptr es:[bx]  ;将属性值加1,改变颜色
             add bx,2
             loop s
             jmp int9ret

 
int9ret:  pop es
             pop cx
             pop bx
             pop ax
             iret
;;;;;;;;;;;;;;;;;;;;清屏;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
clearscreen:push bx
              push cx
              push es
              mov bx,0b800h
              mov es,bx
              mov bx,0
              mov cx,2000
clears:    mov byte ptr es:[bx],' '
              add bx,2
              loop clears
              pop es
              pop cx
              pop bx
              ret
;;;;;;;;;;;;;;;;;;;;;;读取系统时间;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;bx定位cmos单元,ds:si定义字符串首地址;;;;;;;;;;;;;;;;;
key4readtime:
                    push ax
                    push bx
                    push cx
                    push ds
                    push si

                    push cs
                    pop ds  ;ds=cs
                    mov bx,offset key4s2-offset boot+7e00h  
                    mov si,offset key4s1-offset boot+7e02h  ;偏移地址  (加多两字节,在前面加字符串'20'.效果:2010/..)
                    mov cx,6

  hms:           push cx
                    mov al,cs:[bx]  ;cmos里的单元
                    out 70h,al
                    in al,71h     ;读出到al

                    mov ah,al
                    mov cl,4
                    shr ah,cl              ;取得高四位
                    and al,00001111b ;把al的高四位全归零,取得低四位
                    add ah,30h
                    add al,30h        ;对应的ASCII
                    mov [si],ah
                    mov [si+1],al 
                    add si,3
                    inc bx
                    pop cx
                    loop hms

                    pop si
                    pop ds
                    pop cx
                    pop bx
                    pop ax
                    ret
;;;;;;;;;;;;;;;;;;;;;延迟一秒;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
delay:    push ax
             push dx
             mov dx,0500h   ;循环N次,可根据自己机器的速度调整次数!
             mov ax,0
 delays:  sub ax,1
             sbb dx,0
             cmp ax,0
             jne delays
             cmp dx,0
             jne delays
 
             pop dx
             pop ax
             ret                
codesg ends
end start
p541938340
[第1楼]   [ 回复时间:2010-03-06 09:36 ]   [引用]   [回复]   [ top ] 
荣誉值:6
信誉值:0
注册日期:2009-09-08 11:48
没人用新中断的方式吗?
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved