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