汇编(五)

  用汇编实现这样一个计时器,正计时60s后退出,要求屏幕显示0-59的秒数。安a键后,保留旧时间,重新另起一行开始计时。

  要实现这样一个功能,需要用到这样几个调用。1CH、35H、25H、08H,同时还要熟悉汇编中如何编写中断程序。

  1CH:该中断没55s由系统调用一次,每秒大概调用18次(非精确数字),我们就是要通过修改这个中断的入口地址,将其指向新中断,从而实现计时。

  35H:INT 21H的获取中断向量功能。AH=35H。入口参数:AL=中断向量号。出口参数:ES:BX=中断服务程序的入口地址(段基地址:偏移地址)。例如,执行mov ax,351ch  int 21H后,将获得1CH的中断程序入口地址,保存在ES和BX寄存器中。

  25H:INT21H的设置中断向量功能。AH=25H。入口参数:AL=中断向量号;DS:DX中断服务程序入口地址(段基地址:偏移地址)。例如,执行mov ax,251CH   int 21H后,将使得1CH中断的入口地址变为DS:DX(需事先将入口地址保存到相应的寄存器中)。

  08H:从键盘读一字符但不回显,此功能调用检查字符是否是Ctrl-Break。

  汇编中的中断编写大致步骤:保存原中断入口地址(35H)->设置新中断入口地址(25H)->执行新中断处理->调用原中断(call指令)->恢复原中断入口地址(25H)

  被程序的实现流程图如下所示:

  

  汇编代码实现如下所示:

;汇编实现计时器
stack segment stack
    db 2014 dup(?)
stack ends
data segment
    old1c dw ?,?
    clock db 0
    flag db 0
    time dw 0
    keyFlag db 0
data ends

code segment 'code'
    assume cs:code,ds:data,ss:stack
start:
    mov ax,data
    mov ds,ax


    mov al,1CH
    mov ah,35H
    int 21H
    mov old1c[0],bx
    mov ax,es
    mov old1c[2],ax
    
    push ds
    mov dx,offset int1c
    mov ax,seg int1c
    mov ds,ax
    mov al,1CH
    mov ah,25H
    int 21H
    pop ds
    
again:
    cmp flag ,1
    jz done
    jmp again
done:
    push ds
    mov dx,old1c[0]
    mov ax,old1c[2]
    mov ds,ax
    mov al,1cH
    mov ah,25H
    int 21H
    pop ds
    mov ax,4c00H
    int 21H
    
int1c proc far
    push dx
    push ax
    sti
    
    mov ax,data
    mov ds,ax
    
    add clock,1
    CMP clock, 1000/55    ;计数器每达到18时秒数加1
    jl finish
    mov clock,0
    ;显示时间
    mov dl,0dH
    mov ah,02H
    int 21H
    mov ax,time
    mov dl,10
    div dl
    mov dl,al
    mov dh,ah
    mov ah,02H
    add dl,30H
    int 21H
    mov ah,02H
    mov dl,dh
    add dl,30H
    int 21H
    
    inc time
    cmp time,60    ;判断是否达到60s
    jl finish
    mov flag,1
    jmp finish2

finish:
    ;判断键盘是否按下?
    mov al,0
    mov ah,0BH
    int 21H
    or al,0
    jnz other
    jmp finish2
other:
    mov ah,08H    ;清除键盘缓冲区
    int 21H
    mov ah,02H
    mov dl,0dH
    int 21H
    mov dl,0ah
    int 21H
    mov time,0    ;重置计时数据
    mov clock,0
finish2:    
    PUSHF
    call dword ptr old1c
    cli
    
    pop ax
    pop dx
    iret
int1c endp

code    ends
    end start

 

 

 

 

 

 

posted @ 2015-10-31 19:41  Num.Zero  阅读(1967)  评论(0编辑  收藏  举报