用MIPS写2019年年历

2019年年历by MIPS

我在写2019年历的时候遇到了比较多的困难,而网上关于MIPS的代码又比较少,所以我在这贴一下我的代码,希望能帮到大家。
独立思考最重要!

.data
cal:	.space 2113
calname:.asciiz "JanFebMarAprMayJunJulAugSepOctNovDec"
start:	.asciiz "Put out the calendar of 2019: \n"
weekday:	.asciiz "SMTWTFS"
monday:	.word 31,28,31,30,31,30,31,31,30,31,30,31
end99:	.asciiz "\nEnding by XiaZeYu919106840637"
.text
main:	la $a0,start	#打印提示语
	li $v0,4
	la $s0,calname
	syscall
	la $s1,cal
	sb $0,2112($s1)	#为空间末尾放置结束符
	li $t0,0x20
	li $t1,0
loop0:	sb $t0,($s1)	#为cal空间全部赋空格
	addi $s1,$s1,1
	addi $t1,$t1,1
	blt $t1,2112,loop0
	li $t0,0
	li $t1,0
	li $s1,0
	li $a0,2	#已知2019年1月1日是星期2
	li $a1,1	#$a1为月份
monLoop:jal month
	move $a0,$v0
	blt $a0,7,go_on0#当weekday为周日时清零
	addi $a0,$a0,-7
go_on0:	addi $a1,$a1,1
	bgt $a1,12,end
	b monLoop
end:	li $t0,0x0a	#为空间内每一层的末尾加上换行符
	la $t1,cal
	addi $t1,$t1,65
	li $t2,1
loop_n:	sb $t0,($t1)
	addi $t2,$t2,1
	addi $t1,$t1,66
	bgt $t2,32,endd
	b loop_n
endd:	la $a0,cal	#输出年历
	li $v0,4
	syscall
	la $a0,end99
	li $v0,4
	syscall
	li $v0,10	#结束
	syscall
month:	addi $a2,$a1,-1	#利用$a2来计算该月份的偏移量
	rem $t5,$a2,3
	mul $t5,$t5,22
	ble $a1,3,add1	#1-3月
	ble $a1,6,add2	#4-6月
	ble $a1,9,add3	#7-9月
	ble $a1,12,add4	#10-12月
add1:	la $a3,cal	#基址在第一大段
	b end_add
add2:	la $a3,cal
	addi $a3,$a3,528#把基址移到第二大段
	b end_add
add3:	la $a3,cal
	addi $a3,$a3,1056#把基址移到第三大段
	b end_add
add4:	la $a3,cal
	addi $a3,$a3,1584#把基址移到第四大段
	b end_add	
end_add:	add $a3,$a3,$t5	#让$a3存储每个月所在缓存区的基址
	#开始初始化每个月份表头
	li $t0,0	#loop1为初始化缓冲区内每个月份的坐标
loop1:	blt $t0,10,kong1
	bgt $t0,12,kong1
	add $t1,$a3,$t0
	lb $t2,($s0)
	sb $t2,($t1)
	addi $s0,$s0,1	#使$s0指向calname字符串中的下一个字符
	addi $t0,$t0,1
	b loop1
kong1:	add $t1,$a3,$t0	#输入空格的循环
	li $t2,0x20
	sb $t2,($t1)
	addi $t0,$t0,1
	bgt $t0,21,go_on1#当过了这个月份就跳出
	bne $t0,9,loop1	#当要输入月份数字时特殊处理
	addi $t0,$t0,-1
	bge $a1,10,ano1	#判断月份是否有十分位
	move $t2,$a1
	addi $t2,$t2,48
	sb $t2,($t1)
	addi $t0,$t0,1
	b loop1
ano1:li $t3,10		#当月份大于10时
	div $a1,$t3
	addi $t1,$t1,-1
	mflo $t2	#将月份的前一位放置
	addi $t2,$t2,48
	sb $t2,($t1)
	addi $t1,$t1,1
	mfhi $t2	#将月份的后一位放置
	addi $t2,$t2,48
	sb $t2,($t1)
	addi $t0,$t0,1
	b loop1
go_on1:	li $t0,0
	li $t1,0
	li $t2,0
	li $t3,0
	li $t5,0	#临时寄存器清零
	#开始初始化星期日期
	addi $t0,$a3,66	#将指针指向基址的下一层
	la $t1,weekday	#用$t1选择weekday
	li $t3,0	#用$t3来记录已初始化天数,达七天跳出
loop2:	li $t2,0x20	#输入空格
	sb $t2,($t0)
	addi $t0,$t0,1
	lb $t2,($t1)	#输入weekday
	sb $t2,($t0)
	addi $t0,$t0,1
	addi $t1,$t1,1
	li $t2,0x20	#输入空格
	sb $t2,($t0)
	addi $t0,$t0,1
	addi $t3,$t3,1	#已初始化天数加一
	bgt $t3,6,go_on2#当初始化完毕则跳出
	b loop2		#继续
go_on2:	li $t2,0x20	#输入两月间的空格
	sb $t2,($t0)
	#开始初始化具体日期
	li $t0,0	#清空临时寄存器
	li $t1,0
	li $t2,0
	li $t3,0
	li $t0,1	#用$t0存储每个月具体的日期,$a0存储这个日期代表星期几
	addi $t1,$a3,132#用$t1指向基址的所在区域的第三层,开始存放日期
	mul $t2,$a0,3
	add $t1,$t1,$t2#使指针指向每个月第一天所在weekday
loop3:	bge $t0,10,ano2#当日期大于十时分类处理
	blt $a0,7,go_on3	#当一个星期满后开始下一个星期
	addi $t1,$t1,-21	#指针跳至下一层
	addi $t1,$t1,66
	addi $a0,$a0,-7		#开始从星期天循环
go_on3:	addi $t1,$t1,1		#输入日期
	addi $t3,$t0,48
	sb $t3,($t1)
	addi $t1,$t1,2
	addi $t0,$t0,1
	addi $a0,$a0,1
	b loop3			#循环
ano2:	mul $t7,$a2,4	#通过$t6,$t7来获取该月的最大天数
	la $t6,monday
	add $t7,$t7,$t6
	lw $t6,($t7)
	bgt $t0,$t6,out_end#当日期超过最大天数时结束函数
	blt $a0,7,go_on4	#同上,判断是否满一个星期
	addi $t1,$t1,-21
	addi $t1,$t1,66
	addi $a0,$a0,-7
go_on4:	li $t3,10		#处理大于10的日期
	div $t0,$t3		#取商为十位,余数为个位放置
	mflo $t3
	addi $t3,$t3,48
	sb $t3,($t1)
	addi $t1,$t1,1
	mfhi $t3
	addi $t3,$t3,48
	sb $t3,($t1)
	addi $t1,$t1,2
	addi $a0,$a0,1
	addi $t0,$t0,1
	b loop3			#循环
out_end:move $v0,$a0		#将下个月的第一天的weekday作为参数返回
	jr $ra

具体的思路是把内存段看成一个二维平面来一个一个放值。

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值