再议汇编判断闰年(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)就可以升级输入数据的长度
