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

📄 闰年判断.asm

📁 汇编语言课程设计--闰年判断
💻 ASM
字号:

assume cs:code,ds:data
data segment;初始化各种提示语句,前面的0dh,0ah表示回车
  inf db 0dh,0ah,'Please Input Year: $'
  inf_ok db 0dh,0ah,'This is a leap year! $'
  inf_no db 0dh,0ah,'This is not a leap year! $'
  inf_err db 0dh,0ah,'Input Error! $'
  inf_ag db 0dh,0ah,'Do you want to try again?(Y/N) $'
  inf_end db 0dh,0ah,'Press any key to exit. $';将输入的年份字符串转为数字,存在此处
 year dw 0;缓冲区,用于接受输入,第一个字节为缓冲区长度,第二个字节为实际输入长度,后面是缓冲区
 buf db 8
 db ?
 db 8 dup (?)
 data ends
 stack segment 
 db 80 dup (0) 
stack ends
code segment
start:
 mov ax,data
 mov ds,ax
 mov ax,stack
mov ss,ax
 mov sp,80;dx保存提示语句的首地址,调用21H中断09功能,显示在屏幕上
 lea dx,inf
mov ax,0900H
 int 21H;dx指向缓冲区首字节(表示缓冲区大小的字节),调用21H中断0AH功能,接受输入字符串
 lea dx,buf
mov ax,0a00H
 int 21H;cx清零
 xor cx,cx
 mov cl,[buf+1];cl取得实际输入字符数
 cmp cl,4 ;如果实际输入字符数>4,则提示输入错误
 ja input_error
 lea si,[buf+2];si指向实际的缓冲区起始位置
 push cx
is_num: ;判断输入的是否都是数字,如果不是,则提示输入错误
 cmp byte ptr [si],'0'
jb input_error
 cmp byte ptr [si],'9'
ja input_error
 inc si ;si后移
loop is_num

pop cx
 dec si ;上面循环结束后,si指向输入字符串的最后一个字符的后面,所以减1,使之指向最后一个字符
 lea di,year ;di指向保存转换后数字的空间
mov word ptr [di],0 
;该空间清0
 call str2int ;调用函数,将输入字符串转换为数字
 call isleap ;判断这个数字是否为闰年
 
jmp short try_again ;询问是否继续输入
input_error:
 lea dx,inf_err ;提示输入错误
 mov ax,0900H
 int 21H
try_again:
 lea dx,inf_ag ;询问是否继续
 mov ax,0900H
 int 21H
 mov ax,0100H ;调用中断21H的01功能,接受一个字符输入并回显
int 21H
 cmp al,'y' ;判断输入字符是否为y或Y,如果是,则跳回函数开头,重新执行
 jz start
cmp al,'Y'
 jz start

main_end:
 lea dx,inf_end
mov ax,0900H
 int 21H
 mov ax,0700H
int 21H
mov ax,4c00H ;程序结束
int 21H

;函数功能:将一个数字字符串转换成对应的数字
;输入参数:cx 字符串长度
; si 指向字符串的最后一个字符
; di 指向转换结果保存的位置,大小为word型
str2int proc near
 push ax ;寄存器入栈
push bx
push cx
 push dx
 mov ax,1 ;ax初始为1
 l1:
 push ax ;每次循环,ax*10,但是后面计算乘法的时候,还需要用到ax,所以先把ax的值入栈
 mov bl,[si] ;把si指向的字符存入bl,并减掉字符'0'
 sub bl,'0'
 mov bh,0 ;bh置0,计算乘法,因为可能要乘1000,只能用16位乘16位的乘法
 mul bx
 add ds:[di],ax ;乘法结果加到保存计算结果的地方(也就是di指向的地址)
 pop ax ;ax出栈,并乘10
 mov bx,10
 mul bx
dec si ;si递减
 loop l1 ;这个循环开头没有写cx,因为cx是作为参数传进来的
 pop dx
pop cx
 pop bx
 pop ax
ret
str2int endp
;函数功能:判断某个数字是否为闰年
;输入参数:di 指向被判断数字的存储地址,word型
;输出参数:无,直接屏幕显示是否闰年
isleap proc near
 push ax ;寄存器入栈
 push bx
 push cx
push dx
 mov cx,ds:[di] ;cx保留输入字符串
 mov ax,cx
 cmp ax,1900
 jl  input_error
 cmp ax,2100
 ja input_error
 mov dx,0 ;因为除法结果可能超过8位,所以要做32位除16位的除法,所以dx要清零
 mov bx,4 ;除4
 div bx
 cmp dx,0 ;dx是余数,判断是否为0,不是0则肯定不是闰年
 jnz not_leap
 mov ax,cx ;ax恢复为待计算数字,这次计算的结果只需要8位就够,所以用16位除8位就行
 mov bx,100 ;除100
 div bl
 cmp ah,0 ;ah是余数,如果为0,那还要继续判断,如果不为0,那就肯定是闰年了
 jnz is_leap
 mov ax,cx ;x恢复为待计算数字,因为要除以400,超过8位,所以用32位除16位除法
mov dx,0 
 mov bx,400
 div bx
 cmp dx,0 ;余数如果为0,说明是闰年
 jz is_leap
 jmp short not_leap ;不是闰年
is_leap:
 lea dx,inf_ok ;是闰年的话,提示是闰年
 mov ax,0900H
 int 21H
 jmp short end_sub
not_leap:
 lea dx,inf_no ;不是闰年的话,提示不是闰年
mov ax,0900H
 int 21H
end_sub:
 pop dx
 pop cx
 pop bx
 pop ax
 ret
isleap endp
code ends
end start

⌨️ 快捷键说明

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