|
主题 : : 关于课程设计二中第3显示时钟:新安装9号中断问题自动执行问题 [待解决] |
回复[ 1次 ]
点击[ 466次 ] | |
荣誉值: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 | | |