欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

再议汇编判断闰年(16位实模式) 补充

再议汇编判断闰年(16位实模式) 补充

判断闰年的算法:(year%4==0)&&(year%100!=0)||year%400==0
一个年份若它能被4整除同时不能被100整除,或能被400整除的年份是闰年
;子程序名:Asc_to_Hex
;功    能:将以 ASCII形式输入的数据转换成为16进制表示的数据
;入口参数:CX = Buf+1
;出口参数:
Asc_to_Hex       PROC     NEAR
       push      cx
       dec       cx
       lea       si,     Buf + 2
;以上内容是将指针计数器 cx 减少一位,作为以后面算法的需要
       
Point_tail:
       inc       si
       loop      Point_tail
;此处就是执行将指针向后移动
;例:首先假设我们输入的是4位数字的年份(例如:2004) cx=4
;以上对CX必须自减1的原因是(以下模拟内存)
;   | ? | 2 | 0 | 0 | 4 | ? |
;         ^(lea si, Buf + 1 指针指向首地址)          如果我们不自减1 cx=4,而计算4次指针会指向未知数据
;如 | ? | 2 | 0 | 0 | 4 | ? |
;                         ^    <-移动 cx=4 指针此时指向的是未知的数据,必然导致输出的错误
;正确应该如下
;   | ? | 2 | 0 | 0 | 4 | ? |
;                     ^        <-cx=3
       pop       cx
       
       mov       dh,     30h
       mov       dl,     10
       mov       bx,     1
       mov       ax,     0
       ;
     
;以上属于赋初值,每个寄存器均有独到的作用
;mov dh, 30h 作用:因为键盘输入的内容属于ASCII码形式,可我们需要的数据是16进制形式,所以要进行转换
;将原ASCII数据 减去 30h 就可以得到对应的16进制数据的形式
;mov dl, 10  作用:作为一个固定的乘积,为以下算法分析铺垫
;mov bx, 1   作用:乘数(数据会改变)
;mov ax, 0   作用:存数用的寄存器(数据会改变)

To_Asc:
       mov       al,     byte ptr [si]
       sub       al,     dh
       push      dx
       mul       bx
       pop       dx
       
       add       Write,   ax
       
       push      ax
       mov       ax,      bx
       mul       dl
       mov       bx,      ax
       pop       ax
       
       dec       si
       loop      To_Asc
       
       ret
Asc_to_Hex       ENDP
;To_Asc的作用:是将每个输入的ASCII码数据提出并且将其变换成为16进制形式
;当把所有数据转换成为16进制形式后,并将其求和计算出对应的数据
;仍然以输入数据 2004 为例
;键盘输入 2004 的数据形式如下: 2(32h) 0(30h) 0(30h) 4(34h) 这些数据都是独立的不能进行我们所需的处理
;如果数据是ASCII码则不能进行闰年判断了,闰年的判断算法是一个年份若它能被4整除同时不能被100整除,或能被400整除的年份是闰年.
;我们需要得到的数据是 2004d(十进制) = 7d4h(十六进制) 而不是独立的ASCII码,所以要将输入的数据转换 这就是和高级语言的差别
;虽然将独立的ASCII码转换成16进制数据,但是依然不能对其进行处理,因为它们仍然是独立的所以要将其合并
;合并的算法: 个位*1 + 十位*10 + 百位*100 + 千位*1000 ... 以此类推
;为什么不从最高位开始,那是因为你不知道输入的到底是哪个年份有可能输入的是 500年 也有可能输入的是10000年
;以上为准备知识,现在对代码进行分析
;       mov       al,     byte ptr [si]
;       sub       al,     dh
;  这段代码的主要作用就是将数据从最后一位开始读取,并且从ASCII形式转换成为16进制形式,然后将其送入寄存器al中
;       push      dx
;       mul       bx
;       pop       dx
       ;由于在乘除法运算过程中 DX AX 会被作为同一个寄存器来处理,故 DX 中的数据会被改变
       ;若不加数据保护 push pop 则 DX 中的数据会被清零,自然也达不到程序处理的要求 
       
;       add       Write,   ax
        ;bx则是位后面的乘数(个位*1 + 十位*10...)
        ;Write 就是将一个个独立的数据相加求和 并且把最终的结果储存
        ;例: (34h-30h)+(30h-30h)+(30h-30h)+(32h-30h) = 2004d = 7d4h
;       push      ax
       ;push      dx  该句就可以添加保护
;       mov       ax,      bx
;       mul       dl
;       mov       bx,      ax       ;bx = 1 或 10 或 100 或 1000
;       pop       ax
;       bx就是乘数 但是最核心的地方在于它保证 bx 每次都是以10倍数增长 但又不破坏其他的数据,于是使用了中间变量dl
;提示:由于使用了寄存器DX,所以在定义数据大小时就限制了输入数据的长度
;输入过长的数据必然导致DX被更改,那样将影响数据的正确性
;该问题可以通过加寄存器保护(push)就可以升级输入数据的长度

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功