| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3736 人关注过本帖
标题:判断闰年
只看楼主 加入收藏
心雨泪
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2008-10-29
收藏
 问题点数:0 回复次数:7 
判断闰年
data segment    ;定义数据段
    infon db 0dh,0ah,'Please input a year: $'
    Y db 0dh,0ah,'This is a leap year! $'
    N db 0dh,0ah,'This is not a leap year! $'
    w dw 0             ;用于保存输入的年份的数值,因为输入的年份是字符串,因此需要转换为数值
                       
                       ;定义输入缓冲区
    buf db 8           ;第一个字节指出能容纳的最大字符个数,由用户给出,这里
                       ;定义了8个字节的缓存区
        db ?           ;第二个字节存放实际输入的字符个数,由系统最后填入
        db 8 dup(?)    ;从第三个字节开始存放键盘接受的字符ASCII码值,直到enter结束键
data ends

stack segment stack
    db 200 dup(0)
stack ends

code segment
          assume ds:data,ss:stack,cs:code
    start:mov ax,data
          mov ds,ax
         
          lea dx,infon  ;在屏幕上显示提示信息。就是目标地址传送指令: 将一个近地址指针写入到
                        ;指定的寄存器。格式:LEA reg16,mem16 其中reg16必须是一个16位通用寄存
                        ;器,mem16必须是一个存储器,执行这个指令后,就将mem16所指的16位偏移地
                        ;传送到reg16中
         
          mov ah,9      ;显示字符串
          int 21h

          lea dx,buf    ;从键盘输入年份字符串
          mov ah,0Ah    ;0AH功能调用从键盘接受字符串到内存的输入缓存区
          int 21h
         
          mov cl, buf+1 ;把输入的字符的个数保存在cl中(第二个字节存放实际输入的字符个数)
          lea di,buf+2  ;把从键盘输入字符的首地址存放到di中
          call datacate ;调用datacate子程序
          call ifyears  ;调用ifyears子程序
          jc a1         ;jump if carry如果进位则跳转
         
          lea dx,n      ;输出不是闰年
          mov ah,9
          int 21h
          jmp exit      ;无条件跳转 跳转到退出返回操作系统
    a1:   lea dx,y      ;输出是闰年
          mov ah,9
          int 21h
    exit: mov ah,4ch    ;返回操作系统
          int 21h
      
 

 datacate proc near     ;用于把表示年份的字符串转换为数值
         
          push cx;      ;进栈操作,保存cx,即字符个数                                                
          dec cx        ;让cx寄存器自减1
          lea si,buf+2  ;把字符串的首地址保存在源地址寄存器SI中
                        ;让si指向字符串的最低位
     tt1: inc si        ;si寄存器中内容增1(inc是增量指令,dec是减量指令)
          loop tt1      ;loop是循环语句
          pop cx        ;出栈操作,与55行进栈操作相呼应
     
      
          mov dh,30h
          mov bl,10
          mov ax,1
      l1: push ax                ;入栈操作,
          sub  byte ptr [si],dh  ;由于字符是ASCII码表示的,因此减去30H后即可转换为十六进制数
          mul  byte ptr [si]     ;计算ax乘以字符数字
          add w,ax               ;把计算结果累加,并保存在w中
          pop ax                 ;出栈操作,去除上一次操作后的倍数
          mul bl                 ;乘以bl,计算当前的倍数
          dec si                 ;修改源地址寄存器si的值,使得si指向下一个字符(即高位)
          loop l1                ;循环直到所有字符处理完毕(本程序中定义buf为8个字节,
                                 ;所以最多八个字符)
          ret                    ;子程序返回指令
 datacate endp


   ifyears proc near             ;此子程序用来判断年份是否为闰年
           
           push  bx              ;将寄存器实行入栈操作是为了保存寄存器状态
           push  cx
           push  dx
           
           mov  ax,w             ;把转换后的年份的数值存入AX
           mov  cx,ax            ;把AX中存储的年份的数值存入CX,作用是复制一个年份数值,
                                 ;留作计算年份是否为100的整数倍用
                                 
                                 ;计算年份是否为4的整数倍
           mov  dx,0             ;把0存放到寄存器dx中(预先将dx清零,为后来除法指令第3种存储方法
                                 ;坐下铺垫)
           mov  bx,4             ;把4存放到寄存器bx中(除数)
           div  bx               ;除法指令
                                 ;1、被除数16位,除数8位:被除数必须放在AX中,相除之后
                                 ;商放在AL中,余数放在AH中
                                 ;2、被除数8位,除数8位:被除数必须放在AL中,AH清零,相除之后
                                 ;商放在AL中,余数放在AH中
                                 ;3、被除数32位,除数16位:被除数必须放在DX,AX中,DX为高高字节
                                 ;商放在AX中,余数放在DX中
                                 ;4、被除数16位,除数16位:被除数必须放在AX中,DX清零,相除之后
                                 ;上放在AX中,余数放在DX中
                                 ;本例中 被除数为ax,整型数据占两个字节16位,除数(即源操作数)
                                 ;为整型数据4,也占两个字节16位,所以按照第3中方式存储
                                 ;余数放在dx中。
           cmp  dx,0             ;将dx中的余数与0进行比较,看似否整除
           jnz  lab1             ;JNZ用来判断比较的结果,如果有不等的数据则跳转。(zf=1则转移)
            
                                 ;判断年份是否为100的整数倍
           mov  ax,cx            ;将前面复制到cx寄存器中的年份的数值传给ax
           mov  bx,100           ;将100赋给bx寄存器,做div的源操作数(除数)
           mov  dx,0
           div  bx               ;本例中 被除数为ax,整型数据占两个字节16位,除数(即源操作数)
                                 ;为整型数据100,也占两个字节16位,所以按照第3中方式存储
           cmp  dx,0             ;将dx中的余数与0进行比较,看似否整除
           jnz  lab2             ;JNZ用来判断比较的结果,如果有不等的数据则跳转。(zf=1则转移)
                                 
                                 ;判断年份是否位400的整数倍
           mov  ax,cx
           mov  bx,400
           mov  dx,0
           div  bx
           cmp  dx,0
           jz   lab2
           
     lab1: clc                   ;清除进位标志,即非闰年(进位标志用于标志是否为闰年)
           jmp lab3              ;jmp无条件转移
     lab2: stc                   ;设置进位标志,即闰年
     lab3: pop  dx               ;出栈操作,寄存器状态。要注意的是出战顺序与入栈顺序是相反的
           pop  cx
           pop  bx
           ret                   ;子程序返回指令
   ifyears endp
code ends
   end start
      


本程序在判断闰年是有一个问题,当大于1000时比如1100按理说不是闰年但是,程序判断出来的确实闰年,小于一千时,判断结果都是对的,比如900判断出来的就不是闰年,这是为什么呀?
搜索更多相关主题的帖子: 闰年 判断 
2008-11-02 19:04
cnhanxiao
Rank: 2
等 级:新手上路
威 望:4
帖 子:124
专家分:0
注 册:2008-10-17
收藏
得分:0 
一般来说,能被4整除的年份是闰年。但是世纪年(xx00年)例外,要能被400整除才是闰年。
比如1900年不是闰年,而2000年是闰年。

我没看你的程序,程序中应该判断是不是世纪年,并相应做出处理。。。

[[it] 本帖最后由 cnhanxiao 于 2008-11-3 12:41 编辑 [/it]]

还有绑架成版主的?拒绝做版主——对不起啊!
2008-11-03 12:39
zhuxiangjie330
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2008-10-9
收藏
得分:0 
我是菜鸟  下面的作用是什么呢、?



push cx;      ;进栈操作,保存cx,即字符个数                                                
          dec cx        ;让cx寄存器自减1
          lea si,buf+2  ;把字符串的首地址保存在源地址寄存器SI中
                        ;让si指向字符串的最低位
     tt1: inc si        ;si寄存器中内容增1(inc是增量指令,dec是减量指令)
          loop tt1      ;loop是循环语句
          pop cx        ;出栈操作,与55行进栈操
2008-11-05 00:21
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
[bo][un]zhuxiangjie330[/un] 在 2008-11-5 00:21 的发言:[/bo]

我是菜鸟  下面的作用是什么呢、?



push cx;      ;进栈操作,保存cx,即字符个数                                                
          dec cx        ;让cx寄存器自减1
          lea si,buf+2  ; ...


就是把那个字符串移到指定区域
2008-11-05 08:50
cnhanxiao
Rank: 2
等 级:新手上路
威 望:4
帖 子:124
专家分:0
注 册:2008-10-17
收藏
得分:0 
回复 4# 的帖子
应该是移动指针到字符串结尾,供后面程序反向写串使用。呵呵,太啰嗦了。

还有绑架成版主的?拒绝做版主——对不起啊!
2008-11-05 13:13
ONEPROBLEM
Rank: 6Rank: 6
来 自:广西 南宁
等 级:贵宾
威 望:21
帖 子:1569
专家分:349
注 册:2008-7-11
收藏
得分:0 
我补充一点,也许对LZ有参考作用:
闰年的满足条件是:
不能被100整除时,却能被4整除;或者,能被100整除时,又能被400整除的;
除此之外,均不是闰年.
所以,可以用伪代码表示如下:
mov ax,年份
mov dx,0
mov bx,100
div bx
cmp dx,0
je  next      ;去判断能否被400整除
mov ax,年份
mov bl,4
div bl
cmp ah,0
je  是闰年,并退出
next:
mov ax,年份
mov dx,0
mov bx,400
div bx
cmp dx,0
je  是闰年,并退出
收到的鲜花
  • zklhp2008-11-05 18:38 送鲜花  50朵   附言:我很赞同
2008-11-05 17:21
masmpig
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2008-11-7
收藏
得分:0 
润年的条件判断问题。
2008-11-07 13:49
快速回复:判断闰年
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.047021 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved