汇编(一):判断闰年

   以前在学java的时候就写过判断闰年的程序,仅仅几行代码就能搞定,判断闰年的方法也很简单,满足下列条件之一者就是闰年:

   1. 能被4整除但不能被100整除

   2. 能被400整除

用java很容易就能实现的功能,用汇编就不见得很容易了,但判断规则这么简单,想必用汇编也不会很难了。

我的思路如下:

  1.  用一个子程序来输入年份,并判断是否有效(有效年份为1900-2100),将输入的年份字符串转换成10进制后保存在AX中作为返回结果

   2.  用一个子程序用来判断是否是闰年,并显示结果信息

  3.  用一个程序来调用两个子程序。

写完代码后,编译时没出现编译错误,心头一阵暗喜。但一运行就有问题了。有些年份明明是闰年,但结果显示不是闰年经过耐心调试,发现在输入结束后进行了换行,换行调用了中断程序,所以AH已经改变!改过后仍然不正确,出现除法溢出错误,调了我好长时间,一度想放弃调试,结果又发现是寄存器使用不当!调试代码的时间是写代码的几倍!深深体会了那一句话:代码是调出来的。

总结这次的错误:

 1. 寄存器使用不小心,同一寄存器要使用在不同方面,改变寄存器时没有保存原来的值没有意识到调用中断时改变了AH的值、进行循环时改变了CX的值。

 2. 堆栈使用不熟练,虽然知道push与pop要配对,在代码中也进行了配对,但在push与pop之间有跳转指令,一旦发生跳转,程序就会发生莫名奇妙的错误。

如果写代码的时候能细心一点,就能少花好多时间了。汇编语言寄存器数量有限,如何合理地利用有限的资源,在使用时不发生冲突,是学习汇编编程所必须的技能,加油!

----------------------------下面是源代码---------------------------------

Code:
  1. ;-----------------------------------------------  
  2. ;输入一个具体的年份(1900-2100),判断是否是闰年  
  3. ;-----------------------------------------------  
  4. ;***********************************************  
  5. data segment  
  6.     inbuff  db 5,?,5 dup(?)  
  7.     prompt  db 'Please input the year(1900-2100):','$'  
  8.     errmsg  db 'Input illegal!','$'  
  9.     yes     db ' is leap year','$'  
  10.     no      db ' is not leap year','$'  
  11.     mess    db 'Continue?(y/n):','$'  
  12.     newline db 13,10,'$'  
  13. data ends  
  14. ;***********************************************  
  15. code segment  
  16. ;-----------------------------------------------  
  17. main proc far  
  18.            assume cs:code,ds:data  
  19. start:  
  20.     push ds  
  21.     sub ax,ax  
  22.     push ax  
  23.   
  24.     mov ax,data  
  25.     mov ds,ax  
  26. lop0:  
  27.     call input  
  28.     call judge  
  29.       
  30.     lea dx,mess  
  31.     mov ah,09h  
  32.     int 21h  
  33.       
  34.     mov ah,01h  
  35.     int 21h  
  36.   
  37.     cmp al,'n'  
  38.     je exit  
  39.   
  40. continue:  
  41.     lea dx,newline  
  42.     mov ah,09h  
  43.     int 21h  
  44.       
  45.     jmp lop0  
  46.       
  47. exit:          
  48.     ret  
  49. main endp  
  50. ;-----------------------------------------------  
  51. ;输入一个具体的年份,并转换成10进制  
  52. ;返回:  
  53. ;*  (ax)=输入的年份  
  54. input proc near  
  55.     push bx  
  56.     push cx  
  57.     push dx  
  58. s1:  
  59.     lea dx,prompt  
  60.     mov ah,09h  
  61.     int 21h  
  62.   
  63.     lea dx,inbuff  
  64.     mov ah,0ah  
  65.     int 21h  
  66.   
  67.     mov dl,byte ptr inbuff[1]  
  68.     cmp dl,4  
  69.     jne error  
  70.   
  71.     mov cx,4  
  72.     lea bx,inbuff  
  73.     add bx,2  
  74.     mov ax,0  
  75.     mov dx,0  
  76. lop1:  
  77.     mov dl,10  
  78.     mul dl  
  79.     mov dl,byte ptr [bx]  
  80.     sub dl,30h  
  81.     cmp dl,0  
  82.     jb error  
  83.     cmp dl,9  
  84.     ja error  
  85.     add ax,dx  
  86.     inc bx  
  87.     loop lop1  
  88.   
  89.     ;检查输入有效性  
  90.     cmp ax,1900  
  91.     jb error  
  92.     cmp ax,2100  
  93.     ja error  
  94.     jmp s2  
  95.   
  96. error:  
  97.     lea dx,newline  
  98.     mov ah,09h  
  99.     int 21h  
  100.   
  101.     lea dx,errmsg  
  102.     mov ah,09h  
  103.     int 21h  
  104.   
  105.     lea dx,newline  
  106.     mov ah,09h  
  107.     int 21h  
  108.     jmp s1  
  109. s2:  
  110.     mov cx,ax  
  111.     lea dx,newline  
  112.     mov ah,09h  
  113.     int 21h  
  114.     mov ax,cx  
  115.   
  116.     pop dx  
  117.     pop cx  
  118.     pop bx  
  119.     ret  
  120. input endp  
  121. ;-----------------------------------------------  
  122. ;判断一个年份是否闰年  
  123. ;输入:  
  124. ;*  (ax)=年份  
  125. judge proc near  
  126.     push bx  
  127.     push cx  
  128.     push dx  
  129.       
  130.     push ax ;保存ax  
  131.     
  132.     ;输出要判断的年份  
  133.     mov cx,4  
  134.     lea bx,inbuff  
  135.     add bx,2  
  136. lop2:  
  137.     mov dl,byte ptr [bx]  
  138.     mov ah,02h  
  139.     int 21h  
  140.     inc bx  
  141.     loop lop2  
  142.   
  143.     pop ax  
  144.     mov dx,0  
  145.     mov cx,ax ;保存ax到cx中  
  146.     ;判断是否能被4整除  
  147.     mov bx,4  
  148.     div bx  
  149.     cmp dx,0  
  150.     jne notleap  
  151.   
  152.     ;判断是否能被100整除  
  153.     mov ax,cx  
  154.     mov bx,100  
  155.     div bx  
  156.     cmp dx,0  
  157.     jne isleap  
  158.   
  159.     ;判断是否能被400整除  
  160.     mov ax,cx  
  161.     mov bx,400  
  162.     div bx  
  163.     cmp dx,0  
  164.     jne notleap  
  165.   
  166. isleap:  
  167.   
  168.     lea dx,yes  
  169.     mov ah,09h  
  170.     int 21h  
  171.     jmp s3  
  172.   
  173. notleap:  
  174.     lea dx,no  
  175.     mov ah,09h  
  176.     int 21h  
  177. s3:  
  178.     ;换行  
  179.     lea dx,newline  
  180.     mov ah,09h  
  181.     int 21h  
  182.       
  183.     pop dx  
  184.     pop cx  
  185.     pop bx  
  186.     ret  
  187. judge endp  
  188. ;-----------------------------------------------  
  189. code ends  
  190. ;***********************************************  
  191.     end start  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值