⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zhongweek.asm

📁 输入一个日期
💻 ASM
字号:
DATA SEGMENT
        ;----------------------------父菜单-----------------------
  FMENU DB 0AH,0DH,'      **************** WELCOM **************** '
        DB 0AH,0DH,'      *         %%%%%%%%%%%%%%%%%%%%         * '         
        DB 0AH,0DH,'      * Operations:                          * '
        DB 0AH,0DH,'      *          [1].  Log  On               * '
        DB 0AH,0DH,'      *          [2].  Get  Day-in-Week      * '
        DB 0AH,0DH,'      *          [3].  Adiminitrator         * '
        DB 0AH,0DH,'      *          [4].  Exit                  * '
        DB 0AH,0DH,'      *                                      * '  
        DB 0AH,0DH,'      ****************************************$'
        DB 0AH,0DH,'Please  select the operation(1-4):$'
        ;----------------------------子菜单------------------------
  CMENU DB 0AH,0DH,'      **************** WELCOM **************** '
        DB 0AH,0DH,'      *          ^     ------     ^          * '  
        DB 0AH,0DH,'      * Operations:                          * '
        DB 0AH,0DH,'      *          [1].  Reset Start Day       * '
        DB 0AH,0DH,'      *          [2].  Reset Passwords       * '
        DB 0AH,0DH,'      *          [3].  Exit                  * '
        DB 0AH,0DH,'      *                                      * '
        DB 0AH,0DH,'      *                                      * '  
        DB 0AH,0DH,'      ****************************************$'
        DB 0AH,0DH,'Please  select the operation(1-3):$'
        ;-----------------------------------------------------------
  Table  DB 31,28,31,30,31,30,31,31,30,31,30;月/天数
  Title  DB 0AH,0DH,'TheDay-in-Week is:$'   ;输出状态提示
  Logon  DB 0AH,0DH,'Please Log On!$'       ;登陆状态提示
  Error  DB 0AH,0DH,'Input  Error!$'        ;错误状态提示
  Passwords DB 80 DUP<8,'C','S','Q','-','1','9','8','6'>          ;原始密码,第一个记录密码长度
  Passtip1  DB 0AH,0DH,'Please enter the passwords(Maxsize=80):$';密码设置提示
  Sdate     DB  0  ;输入密码状态标志
  Passtip2  DB 0AH,0DH,'Please enter the new passwords(Maxsize=80):$'
  Yes       DB 0AH,0DH,'OK!$'              ;设置状态
  Tipsetday DB 0AH,0DH,'Format:Year/Month/Day/Postion-Week$';输入格式提示
  Daystart  DW 2006,12,21,4                ;初始:年/月/日/星期X
  BUF       DB 80                          ;键盘输入缓冲区
            DB ?
            DB 80 DUP(?)
  Today     DW 4  DUP(0)                   ;当前输入的待查询日期
DATA ENDS 
STACK SEGMENT STACK
   DB 100 DUP(?)
STACK ENDS
CODE  SEGMENT
      ASSUME CS:CODE,DS:DATA,SS:STACK
      ;-----主函数-类While(1)循环----
       MAIN:MOV AX,DATA
            MOV DS,AX
            CALL F
      ;------------------------------
      ;---------------父菜单功能实现-子程序1-------------------
      F PROC NEAR 
        PUSH DX      ;现场保护DX,菜单项
        PUSH AX      ;现场保护AX,操作码
         FREPIT:LEA  DX,FMENU    ;载入父菜单      
                CALL DISTR       ;屏幕显示父菜单
                MOV  AH,1        ;选择服务项
                INT  21H          
                SUB  AL,30H      ;执行选择命令,数据校验
                CMP  AL,1        ;必须先登陆,从菜单起始下标起
                JNZ  TO_L        ;后备的身份校验
                CMP  AL,2        
                JZ   TO_P        ;键入日期的位置---------主功能  
                CMP  AL,3        
                JZ   TO_C        ;进入管理区
                CMP  AL,4        
                JZ   TO_E        ;退出        
                CALL TO_D        ;默认操作               
                POP  AX          ;现场恢复 
                POP  DX
                JMP  FREPIT      ;返回主菜单
           TO_L:LEA  DX,Logon
                CALL DISTR
                JMP  FREPIT      ;返回主菜单
           TO_P:LEA  DX,Tipsetday;输入日期提示
                CALL DISTR
                CALL OUTROW      ;输出换行
                PUSH CX
                PUSH AX
                MOV  CX,4       
                 LP1: LEA DX,BUF    ;键盘依次输入年/月/日/星期
                      MOV AH,10   
                      INT 21H    
                      PUSH CX       ;开始码制转换
                      PUSH BX
                      MOV  CX,BUF[1];输入的字符串长度
                      MOV  DL,10     
                      MOV  SI,2     ;从第二个字节开始存放的
                   L1:MOV  AL,BUF[SI] 
                      SUB  AL,30H   ;转换为数值型
                      CMP  SI,2     ;是否为原数的第一位
                      INC  SI       ;后移
                      JNZ  A1
                      MOV  BL,AL    ;根据算法需求,保存第一位
                      JMP  L1
                    A1:XCHG AL,BL;刚输入的值与前几位值交换存储
                       MUL  DL
                       ADD  AL,BL
                       MOV  BL,AL
                    LOOP L1      ;子循环,缺点:只可转换一个正数( < 2560 ) 
                       POP BX
                       POP CX
                       MOV Today[4-CL],AX;保存经转换后的数字                                    
                  LOOP LP1
                       MOV DX,0   ;测试初始年是否为闰年           ;算法:1>  据已知的Daystart(设为s年sx月sy日si星期数)推断该年是否为闰年;
                       MOV AX,Daystart[0]                         ;     2>  并推断该年1月1日的星期数,S=((累加sx)+sy-1)%7(1<=i<=sx),S1.1=(si+7-S)%7
                       MOV CL,4                                   ;     3.1>当待求E>S时,推断e年1月1日的星期数为
                       DIV CL                                     ;         (S1.1+闰年数+(e-s))%7, 其中,闰年数=(|e-s|)/4+(e%4&&s%4)
                       CMP DL,0   ;确定是否闰年                   ;     3.2>当待求e<s时,推断e年1月1日的星期数为
                       JNZ FDAY                                   ;         (S1.1+7-(s-e+闰年数)%7)%7
                       MOV TABLE[1],TABLE[1]+1;若为闰年则二月29天 ;     4>计算e年ex月ey日的星期数为
                       MOV AX,0                                   ;         (ei+ey+i)%7
                       MOV CX,Today[1]-1
                  FDAY:ADD  AL,TABLE[CL]      ;求si之和                                       
                       LOOP FDAY
                       ADD  AL,PTR BYTE Today[5]-1;求累加si +sy-1       
                       MOV  DX,0                     
                       MOV  CL,7                              
                       DIV  CL                ;S
                       MOV  CX,Daystart[3]
                       ADD  DH,CL+7-DL
                       ;MOV  DL,0 
                       ;MOV  PTR BYTE Today[7],DH
                       CMP  DH,7
                       JA   S1                  ;S1.1的星期数DH
                       CMP  Today[0],Daystart[0];比较E与S大小 
                       JA   S2
                     

  
                  LEA  DX,Title
                  CALL DISTR
                  ADD  Today[3],30H;显示星期数
                  MOV  DL,Today[3]
                  INT  21H 
                  POP  AX    ;现场恢复
                  POP  CX 
                S1:SUB DH,7
                S2:SUB  
                S3: 
                JMP  FREPIT  ;返回主菜单
           TO_C:CALL P_WORD      ;验明身份
                CALL C           ;进入子菜单
                JMP  FREPIT      ;返回主菜单    
           TO_E:CALL EXIT        ;退出系统
           TO_D:LEA  DX,Error
                CALL DISTR   
                JMP  FREPIT      ;返回主菜单
             T :RET              ;返回主调函数 
       F ENDP
       ;-----------------子菜单功能实现-子程序2-----------------
       C PROC NEAR
         PUSH DX      ;现场保护DX,菜单项
         PUSH AX      ;现场保护AX,操作码
          CREPIT:LEA  DX,CMENU    ;载入子菜单      
                 CALL DISTR       ;屏幕显示子菜单
                 MOV  AH,1        ;选择服务项
                 INT  21H          
                 SUB  AL,30H      ;执行选择命令,数据校验
                 CMP  AL,1        
                 JNZ  R_S         ;重设初始日期
                 CMP  AL,2        
                 JZ   R_P         ;重设密码  
                 CMP  AL,3         
                 JZ   R_E         ;退出           
                 CALL R_D         ;默认操作
             R_S:LEA  DX,Tipsetday
                 CALL DISTR       ;换行
                 PUSH CX
                 PUSH AX
                 MOV  CX,4       
                 LP1: LEA DX,BUF    ;键盘依次输入年/月/日/星期
                      MOV AH,10   
                      INT 21H    
                      PUSH CX       ;开始码制转换
                      PUSH BX
                      MOV  CX,BUF[1];输入的字符串长度
                      MOV  DL,10     
                      MOV  SI,2     ;从第二个字节开始存放的
                   L1:MOV  AL,BUF[SI] 
                      SUB  AL,30H   ;转换为数值型
                      CMP  SI,2     ;是否为原数的第一位
                      INC  SI       ;后移
                      JNZ  A1
                      MOV  BL,AL    ;根据算法需求,保存第一位
                      JMP  L1
                    A1:XCHG AL,BL   ;刚输入的值与前几位值交换存储
                       MUL  DL
                       ADD  AL,BL
                       MOV  BL,AL
                    LOOP L1         ;子循环,缺点:只可转换一个正数( < 2560 ) 
                       POP BX
                       POP CX
                       MOV Daystart[4-CL],AX;保存经转换后的数字                                    
                  LOOP LP1
                       POP AX     ;现场恢复
                       POP CX
                   LEA  DX,Yes    ;设置成功!
                   CALL DISTR
                   JMP  CREPIT    ;返回子菜单 
             R_P:CALL P_WORD      ;验明身份
                 CMP  Sdate,1
                 JNZ  R           ;返回主调函数    
                 LEA  DX,Passtip2 ;密码设置提示
                 CALL DISTR 
                 PUSH CX
                 MOV  CX
                 MOV  SI,1
              ON:MOV  AH,8        ;无回显密码输入
                 CMP  AL,0DH      ;是否为回车?
                 JZ   Y
                 MOV  Passwords[SI],AL ;保存密码
                 INC  SI
                 LOOP ON               ;直到空格或输入超过80
                 MOV  Passwords[0],SI-1;记录新密码长度
               Y:LEA  DX,Yes
                 CALL DISTR
                 POP  CX
                 JMP  R          ;返回主调函数
             R_E:CALL EXIT       ;退出系统
             R_D:LEA  DX,Error
                 CALL DISTR   
                 JMP  CREPIT     ;返回子菜单
              R :RET               
        C ENDP
        ;---------------------------------------------------------------
     
        ;-----------------------------------
        ;密码验证
        P_WORD PROC NEAR 
               PUSH CX           ;现场保护
               MOV  CX,3         ;容许密码输入的最大次数 
           LOP:PUSH DX           ;现场保护
               PUSH AX
               PUSH CX
               MOV  CX,Passwords[0];密码长度
               MOV  SI,1
               LEA  DX,Passtip1 
               CALL DISTR        ;连续输入直到回车
           LOP1:MOV  AH,8        ;无回显密码输入
                CMP  AL,0DH      ;是否为回车?
                JNZ  GO_ON       ;逐位验证密码
                MOV  DI,1        ;比较起始地址
             COMP:CMP  Passwords[DI],BUF[DI]
                  JNZ  WRONG
                  LOOP COMP
                  LEA  DX,Yes    ;密码正确
                  CALL DISTR
                  MOV  Sdate,1   ;输入密码正确标志
                  JMP  R         ;返回主调函数
            GO_ON:MOV BUF[SI],AL ;逐位输入缓冲区 
                  JMP LOP1  
            WRONG:LEA  DX,Error  ;输出密码错误
                  CALL DISTR
                  CALL OUTROW 
                  POP CX         ;现场恢复
                  POP AX           
                  POP DX 
             LOOP LOP            ;三次未通过则自动退出 
                  POP  CX          
               R: RET              
        P_WORD ENDP      
        ;-----------------------------------      
        ;退出系统
         EXIT   PROC NEAR         
                MOV  AH,4CH
                INT  21H
                RET 
         EXIT ENDP
        ;-----------------------------------
        ;输出换行
         OUTROW PROC NEAR            
                PUSH DX
                MOV  DL,0AH
                MOV  AH,2
                INT  21H
                POP  DX
                RET
         OUTROW ENDP
        ;------------------------------------
        ;输出字符串
         DISTR PROC NEAR           
                MOV AH,9
                INT 21H
                RET
         DISTR ENDP
        ;------------------------------------
CODE ENDS
     END MAIN



     
       
                     

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -