1 data segment ;定义数据段
2 infon db 0dh,0ah,'Please input a year: $'
3 Y db 0dh,0ah,'This is a leap year! $'
4 N db 0dh,0ah,'This is not a leap year! $'
5 w dw 0
6 buf db 8
7 db ' '
8 db 8 dup(' ')
9 data ends
10
11 stack segment stack
12 db 200 dup(0)
13 stack ends
14
15 code segment
16 assume ds:data,ss:stack,cs:code
17 start:mov ax,data
18 mov ds,ax
19 mov w,0h
20
21 lea dx,infon ;在屏幕上显示提示信息
22 mov ah,9 ;21号ah放09H,dx为串地址,字符串以'$'结束
23 int 21h
24
25 lea dx,buf ;从键盘输入年份字符串
26 mov ah,0AH ;从键盘存在缓冲区,DX=缓冲区首址,DX为缓冲区最大大小,DX+1实际输入字符串数
27 int 21h
28
29 mov ch, 0h ;将实际输入长度放进cl中
30 mov cl, [buf+1]
31 lea di,buf+2 ;将字符串首址放在di中
32 call datacate
33 call ifyears
34 jc a1 ;进位为1则转移=jb,即闰年转移
35
36 lea dx,n ;显示不是闰年
37 mov ah,9
38 int 21h
39 jmp start
40 a1: lea dx,y ;显示是闰年
41 mov ah,9
42 int 21h
43 jmp start
44
45 exit: mov ah,4ch
46 int 21h
47
48
49
50 ;之前要准备好:将输入结果放进w中
51 datacate proc near;
52 push cx;
53 dec cx
54 lea si,buf+2
55 tt1: inc si ;loop的停止条件cx=0,cx自减
56 loop tt1 ;把字符串指针移到字符串最后
57 pop cx
58
59
60 mov dh,30h
61 mov bl,0Ah
62 mov ax,1 ;乘的时候要用
63 l1: push ax
64 sub byte ptr [si],dh ;sub dst,src减去'0',强制类型转换
65 mul byte ptr [si] ;mul src:字节操作:(AX)<-(AL)*(SRC) 字操作:(DX,AX)<-(AX)*(SRC) ;这里al做乘,当年份为较大时就会出错
66 add w,ax ;将这一位取出的数字所对应的整数加到w中
67 pop ax
68 mul bl ;ax原来为1以后每次乘10
69 dec si
70 loop l1
71 ret
72 datacate endp
73
74 ;计算是否为闰年,w存储年的数值,结果通过改变进位标志位来返回CF
75 ifyears proc near
76 push bx ;保护
77 push cx
78 push dx
79 mov ax,w ;将上面转换的整数值给ax
80 mov cx,ax ;让cx=ax=w,cx保存数据
81 mov dx,0 ;dx清0
82 mov bx,4 ;bx=4
83 div bx ;div SRC 字:(AL)=(AX)/(SRC)商 字节(AX)=(DX,AX)/(SRC)
84 cmp dx,0 ;是否可以整出4
85 jnz lab1
86 mov ax,cx ;是否可以整除100
87 mov bx,100
88 div bx
89 cmp dx,0
90 jnz lab2
91 mov ax,cx ;可以整除400
92 mov bx,400
93 div bx
94 cmp dx,0
95 jz lab2
96 lab1: clc ;不是闰年[clc 将进位位CF清零,即CF=0.]
97 jmp lab3 ; [STC(进位位置为1指令)]
98 lab2: stc ;不能整除100,但能整除4 + 可以整除400
99 lab3: pop dx
100 pop cx
101 pop bx
102 ret
103 ifyears endp
104 code ends
105 end start