+ -
当前位置:首页 → 问答吧 → 关于循环不停调用的问题

关于循环不停调用的问题

时间:2011-06-04

来源:互联网

Assembly code
        DATA  SEGMENT
       INFON  DB        0DH,0AH,' input a year: $'
           Y  DB        0DH,0AH,'This is a leap year! $'
           N  DB        0DH,0AH,'This is not a leap year! $'
           E  DB        0DH,0AH,'Error!  $'
           W  DW        0           ;用于保存输入的年份的数值,因为输入的年份是字符串,因此需要转换为数
         BUF  DB        8           ;定义输入缓冲区
              DB        ?
              DB        8 DUP(?)
        DATA  ENDS
      STACK1  SEGMENT   STACK
              DB        200 DUP(0)
      STACK1  ENDS
        CODE  SEGMENT
              ASSUME    DS:DATA,SS:STACK1,CS:CODE
      START:  MOV       AX,DATA
              MOV       DS,AX
              LEA       DX,INFON    ;在屏幕上显示提示信息
              MOV       AH,9        ;显示字符串
              INT       21H
              LEA       DX,BUF      ;从键盘输入年份字符串
              MOV       AH,0AH      ;0AH功能调用从键盘接受字符串到内存的输入缓存区
              INT       21H
              MOV       CL, BUF+1   ;把输入的字符的个数保存在cl中
              LEA       DI,BUF+2    ;把从键盘输入字符的首地址存放到di中
              PUSH      AX
         A0:
              MOV       AL,[DI]
              CMP       AL,0DH
              JZ        A1
              CMP       AL,'9'
              JG        A3
              CMP       AL,'0'
              JL        A3
              INC       DI
              JMP       A0
         A1:
              POP       AX
              CALL      DATACATE    ;调用datacate子程序
              CALL      IFYEARS     ;调用ifyears子程序
              JC        A2          ;如果进位则跳转
              LEA       DX,N        ;输出不是闰年
              MOV       AH,9
              INT       21H
              JMP       EXIT
         A2:  LEA       DX,Y        ;输出是闰年
              MOV       AH,9
              INT       21H
              CALL      EXIT
         A3:  LEA       DX,E
              MOV       AH,9
              INT       21H
       EXIT:  MOV       AH,0
              INT       16H
              JMP       START
              MOV       AH,4CH      ;返回操作系统
              INT       21H
    DATACATE  PROC      NEAR        ;用于把表示年份的字符串转换为数值
              PUSH      CX          ;
              DEC       CX          ;让cx寄存器自减1
              LEA       SI,BUF+2    ;把字符串的首地址保存在源地址寄存器SI中让si指向字符串的最低位
         P1:  INC       SI
              LOOP      P1
              POP       CX
              MOV       DH,30H
              MOV       BL,10
              MOV       AX,1
         P2:  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      P2          ;循环直到所有字符处理完毕(
              RET                   ;子程序返回指令
    DATACATE  ENDP
     IFYEARS  PROC      NEAR        ;此子程序用来判断年份是否为闰年
              PUSH      BX
              PUSH      CX
              PUSH      DX
              MOV       AX,W        ;把转换后的年份的数值存入AX
              MOV       CX,AX
              MOV       DX,0        ;将dx清零
              MOV       BX,4        ;把4存放到寄存器bx中(除数)
              DIV       BX          ;除法指令
              CMP       DX,0        ;将dx中的余数与0进行比较,看似否整除
              JNZ       LAB1        ;若不相等跳转
              MOV       AX,CX       ;判断年份是否位400的整数倍
              MOV       BX,100      ;将100赋给bx寄存器,做div的源操作数
              MOV       DX,0
              DIV       BX
              CMP       DX,0        ;将dx中的余数与0进行比较,看似否整除
              JNZ       LAB2
              MOV       AX,CX       ;判断年份是否位400的整数倍
              MOV       BX,400
              MOV       DX,0
              DIV       BX
              CMP       DX,0
              JZ        LAB2
       LAB1:  CLC                   ;清除进位标志,即非闰年
              JMP       LAB3
       LAB2:  STC                   ;设置进位标志,即闰年
       LAB3:  POP       DX
              POP       CX
              POP       BX
              RET                   ;子程序返回指令
     IFYEARS  ENDP
        CODE  ENDS
              END       START


判断闰年的程序,在EXIT的子程序中,加入了JMP START代码后,虽然可以达到循环输入的目的,可是为什么输入几组数据后判断结果会出现错误

作者: ryusonfrex   发布时间: 2011-06-04

程序格式漂亮,但是调试支持做的很差。

建议将每次输入后的值,转成数字的值,以及闰年判断中个步骤的值在每次输入后

打印出来,这样想找不到错误都很难啦

作者: mydo   发布时间: 2011-06-04