回 帖 发 新 帖 刷新版面

主题:关于显示系统时间,急!!!

[em18]
1.不用DOS调用,如何显示系统时间;
2.如何判断闰年;

回复列表 (共3个回复)

沙发

;不通过中断来读取或设置时间,主要是读CMOS里的时间,通过70h,71h端口来实现,我编了一个,看看适合你不,已试过能够运行,你可以修改一下本机时间多试试。
;===============================================================================
;1、能被400整除是闰年。
;2、不能被100整除的,但能被4整除的是闰年。
;===============================================================================
;CMOS的读写完全靠 PORT 70h 和 71h 来读写其信息 ,其方法如下∶
;先     OUT 70h,Address
;      然后   IN  AL,71h(读) 或 OUT 71h,AL(写)
;      其 Address 共有64bytes可用(即00-3Fh) ,各位意义可能是.....
;                                                   ^^^^^^
;      00    秒 (BCD码表示)
;      01    无用 (内容为00)
;      02    分 (BCD码表示)
;      03    无用 (内容为00)
;      04    时
;      05    无用 (内容为00)
;      06    不详
;      07    日
;      08    月
;      09    年
;      0A-0E 不详
;      0F    Shadow states
;      10    Floppy A.B (NONE=0 ,360K=1 ,1.2MB=2 ,720K=3 ,1.44MB=4)
;      11    NONE
;      12    Hard Disk C.D (前面TYPE0Eh ,超过则搭配19-2Dh表示至TYPE4?)
;      13    NONE
;      14    配备
;      15&16 Base Memory
;      17&18 Memory
;      19-2D 无用...一般被拿来做 HD type 0E-4x
;      2E-2F CheckSum (只对某几个byte做CheckSum)
;      30&31 Memory
;      32    年代
;      33    刚开机为 01 ,无啥用处
;      34-3F 无用(常被拿来做User Type的信息 ,但最后几个byte仍没用到)
;   例如您想要读取时间 ,则下达
;        out 70h,00
;        in  al,71h
;   ===> al 即为时间值 (每次读取前请先 out 70h 一次)
;        如果您更改时间以外的值 ,请注意CheckSum ,以免下次开机会有
;        CMOS Failure RUN SETUP ....
;        其中每种 BIOS 都会有某几个位未用到 ,于是就可拿来上保护罗,
;        但是请小心 ,如主机板电池没电就不适用此法.
;    例如您先执行
;        out 70h,3fh
;        out 71h,01h
;   ===> 将CMOS没用的部份做一标志(01) ,以后只要
;        out 70h,3fh
;        in  al,71h
;   ===> 若 al=01 就代表合格 ,其它值不合格
;        可用任意值代替此标志 ,惟最好不要用 00h & 80h ,因为很多主机刚
;        开机设定完 CMOS ,此地方值即为上述值。
;===============================================================================

data    segment
    assume    ds:data    
date    db 'Year-month-day  hour:minute:second',0dh,0ah
    db 'Now current date and time is:',24h
string1    db 0dh,0ah,'NO!',24h    ;不是闰年
string2    db 0dh,0ah,'Yes!',24h    ;是闰年
year    dw ?            ;保存年,如2006
flag    db 0
data    ends

code    segment
    assume    cs:code
main    proc    near
    mov    ax,data
    mov    ds,ax
    
    mov    ah,09h            ;显示字符串
    mov    dx,offset date
    int    21h

    mov    al,32h            ;输出年代
    out    70h,al
    in    al,71h                
    call    output1
    mov    byte ptr year + 1,al    ;保存年的高两位,如果是2006年,那么这里保存的是20    
        
    mov    al,09h            ;输出年
    out    70h,al        
    in    al,71h    
    call    output1    
    mov    byte ptr year,al    ;保存年的低两位,如06,等下用来计算是不是闰年
    
    mov    dl,'-'            ;输出分格符 -
    call    output2        
    
    mov    al,08h            ;输出月
    out    70h,al
    in    al,71h
    call    output1
    
    mov    dl,'-'            ;输出分格符 -
    call    output2        
    
    mov    al,07h            ;输出日
    out    70h,al
    in    al,71h
    call    output1
    
    mov    dl,' '            ;输出分格符两个空格
    call    output2
    mov    dl,' '
    call    output2                    

    mov    al,04h            ;输出时
    out    70h,al    
    in    al,71h
    call    output1
    
    mov    dl,':'            ;输出分格符 :
    call    output2            

    mov    al,02h            ;输出分
    out    70h,al
    in    al,71h
    call    output1
                
    mov    dl,':'            ;输出分格符 :
    call    output2        

    mov    al,00h            ;输出秒
    out    70h,al
    in    al,71h
    call    output1    
    
    call    years            ;判断是不是闰年
        
    cmp    flag,0            ;不是闰年就跳转
    je    isnot
    mov    dx,offset string2    ;是闰年
    jmp    exit    
isnot:    mov    dx,offset string1    ;不是闰年
                
exit:    mov    ah,09h    
    int    21h
    
    mov    ah,00h
    int    16h
    
    mov    ah,4ch
    int    21h
main     endp
output1    proc    near
    push    ax
    push    bx
    push    cx
    
    mov    bl,al            ;由于CMOS中保存的数是BCD码,所以要转换一下
    mov    cl,4
    shr    al,cl
    add    al,30h
    mov    ah,02h
    mov    dl,al
    int    21h
    mov    al,bl
    and    al,0fh
    add    al,30h
    mov    ah,02h
    mov    dl,al
    int    21h
    
    pop    cx
    pop    bx
    pop    ax    
    ret

output1 endp
output2    proc    near
        
    mov    ah,02h    
    int    21h    
    ret
    
output2 endp
years    proc    near
    push    ax
    push    bx
    push    cx
    push    dx
    
    mov    ax,word ptr year    ;将BCD码2006年,转换成十六进制数7D6h
    mov    cx,4
    rol    ax,cl
    push    ax
    and    ax,0fh
    mov    bx,1000        
    mul    bx
    mov    word ptr year,ax
    
    pop    ax
    rol    ax,cl
    push    ax
    and    ax,0fh
    mov    bx,100
    mul    bx
    add    word ptr year,ax
    
    pop    ax
    rol    ax,cl
    push    ax
    and    ax,0fh
    mov    bx,10
    mul    bx
    add    word ptr year,ax
    
    pop    ax
    rol    ax,cl
    and    ax,0fh
    add    word ptr year,ax    
    
    xor    dx,dx                ;判断能不能被400整除
    mov    ax,word ptr year        
    mov    bx,400
    div    bx
    cmp    dx,0
    jz    setflag                ;能被400整除则是闰年
    
    xor    dx,dx                ;如果不能被400整除再看看能不能被4整除
    mov    ax,word ptr year        ;如果能被4整除,但不能被100整除,那么
    mov    bx,4                ;也是闰年,例如2000年是闰年,2004年也是闰年
    div    bx
    cmp    dx,0
    jz    y_di100
    mov    flag,0
    jmp    y_exit
y_di100:xor    dx,dx
    mov    ax,word ptr year
    mov    bx,100
    div    bx
    cmp    dx,0
    jne    setflag
    mov    flag,0
    jmp    y_exit          
setflag:mov    flag,1
y_exit :pop    dx
    pop    cx
    pop    bx
    pop    ax
    ret

years     endp
code    ends
    end    main        

板凳


Dank shon![em12]

3 楼

Not at all

我来回复

您尚未登录,请登录后再回复。点此登录或注册