当前位置: 代码迷 >> 汇编语言 >> 显示数字时钟,键盘控制,该怎么处理
  详细解决方案

显示数字时钟,键盘控制,该怎么处理

热度:8005   发布时间:2013-02-26 00:00:00.0
显示数字时钟,键盘控制
写了个程序,动态显示数字时钟,本来要求程序开始等待击键活动才显示时钟。而后击空格键返回DOS。可是我的程序一运行就显示出了时钟,并没有循环检测是否有击键。而且一运行就停不下来。改来改去总不对,烦死了,帮忙看下。
Assembly code
assume cs:codecode segmenttime db 'hh:mm:ss',13,10,'$'string db 'press any key to continue...',13,10,'$'cmos db 4,2,0start:     ;装入代码段的段地址     mov ax,cs     mov ds,ax     mov dx,offset string  ;取得字符串的偏移地址     mov ah,9     int 21H         ;调用DOS显示字符串check:     ;读取键盘的输入状态     mov dl,0ffH     mov al,06H     mov ah,0cH     int 21H     inc al       ;如键盘有击键,al为OFFH。否则为00H     loopnz checkagain:     ;寄存器初始化     mov bx,0     mov si,0     mov cx,3second:     push cx     mov al,cmos[bx]     out 70h,al    ;将al送入地址端口70h     in al,71h ;从数据端口71h处读出单元内容     mov ah,al     mov cl,4     shr al,cl ;右移4位     and ah,0fh    ;al分成两个表示BCD码值的数据     add ax,3030h  ;BCD码+30h=10进制数对应的ASCII码     mov cs:[si],ax     ;ASCII码写入time段     inc bx     add si,3    ;si加上3,指向当前位置的后面第三个位置     pop cx     loop second;名称:BIOS中断(int 10h);功能:(ah)=2置光标到屏幕指定位置、(ah)=9在光标位置显示字符;参数:(al)=字符、(bh)=页数、(dh)=行号、(dl)=例号;      (bl)=颜色属性、(cx)=字符重复个数     mov ah,2 ;置光标     mov bh,0 ;第0页     mov dh,20 ;dh中放行号     mov dl,30 ;dl中放例号     int 10h;名称:DOS中断(int 21h);功能:(ah)=9显示用'$'结束的字符串、(ah)=4ch程序返回;参数:ds:dx指向字符串、(al)=返回值     mov dx,0     mov ah,9     int 21h     ;调用0C功能清空键盘缓冲区并调用06号键盘功能     mov dl,0ffH     mov ah,0cH     mov al,06H     int 21H     cmp al,0      ;判断是否有字符可读,如没有则al为0     je again      ;没有字符可取,跳转到程序的开始     cmp al,0EH    ;如果有击键活动,则获取击键的扫描码,如果输入为空格则程序结束     je exit     jmp again     ;如果输入的不是空格键,则无条件跳转到开始;结束exit:     mov ax,4c00h     int 21hcode endsend start


------解决方案--------------------------------------------------------
Assembly code
assume cs:codecode segmenttime db 'hh:mm:ss',13,10,'$'string db 'press any key to continue...',13,10,'$'cmos db 4,2,0start:     ;装入代码段的段地址     mov ax,cs     mov ds,ax     mov dx,offset string  ;取得字符串的偏移地址     mov ah,9     int 21H         ;调用DOS显示字符串check:     ;读取键盘的输入状态     mov dl,0ffH     mov al,06H     mov ah,06H    ;** 0ch -> 06h  0ch 功能会清输入缓冲区的,所以很难等到按键然后继续     int 21H     ; test al, al       ;** 06h 功能返回时会设置 ZF 状态的,所以可直接使用     loopz checkagain:     ;寄存器初始化     mov bx,0     mov si,0     mov cx,3second:     push cx     mov al,cmos[bx]     out 70h,al    ;将al送入地址端口70h     in al,71h ;从数据端口71h处读出单元内容     mov ah,al     mov cl,4     shr al,cl ;右移4位     and ah,0fh    ;al分成两个表示BCD码值的数据     add ax,3030h  ;BCD码+30h=10进制数对应的ASCII码     mov cs:[si],ax     ;ASCII码写入time段     inc bx     add si,3    ;si加上3,指向当前位置的后面第三个位置     pop cx     loop second;名称:BIOS中断(int 10h);功能:(ah)=2置光标到屏幕指定位置、(ah)=9在光标位置显示字符;参数:(al)=字符、(bh)=页数、(dh)=行号、(dl)=例号;      (bl)=颜色属性、(cx)=字符重复个数     mov ah,2 ;置光标     mov bh,0 ;第0页     mov dh,20 ;dh中放行号     mov dl,30 ;dl中放例号     int 10h;名称:DOS中断(int 21h);功能:(ah)=9显示用'$'结束的字符串、(ah)=4ch程序返回;参数:ds:dx指向字符串、(al)=返回值     mov dx,0     mov ah,9     int 21h     ;调用0C功能清空键盘缓冲区并调用06号键盘功能     mov dl,0ffH     mov ah,06H  ;** 0ch -> 06h  0ch 功能调用会清输入缓冲区,所以应使用 06h     mov al,06H     int 21H     cmp al,0      ;判断是否有字符可读,如没有则al为0  ;** 这两条指令多余     je again      ;没有字符可取,跳转到程序的开始     cmp al,20H    ;** 如果是空格,应该为 20h。0eh 是 Ctr+N!     je exit     jmp again     ;如果输入的不是空格键,则无条件跳转到开始;结束exit:     mov ax,4c00h     int 21hcode endsend start
  相关解决方案