#支持两种功能：浮点数的表示（转化）与浮点数与计算器

.data        #数据段
begin:  	.asciiz "Welcome ! Here are the the selections:"
selection1: 	.asciiz "\n    1. conversion \n    2. calculation\n    3. exit\n"
selection2: 	.asciiz "    1. add +\n    2. substruct -\n"
conver_in: 	.asciiz "Please input a decimal float number: "
num1: 	    .asciiz "Please input the first number: "
num2: 	    .asciiz "Please second the second number: "
dec_out:	    .asciiz "decimal result: "
bin_out:	    .asciiz "\nBinary result: "
hex_out:	    .asciiz "\nhexadecimal result: "
error:		    .asciiz "\nIncorrect input ! Please re-enter: \n"
end:		    .asciiz "================= END  =================="

.text
.globl __start
__start:
	la	$a0,	begin
	li	$v0,	4
	syscall


#交互界面模块
selection_1: 
	la	$a0,	selection1
	li	$v0,	4
	syscall
	li	$v0,	5
	syscall

	move	$t0,	$v0
	beq	$t0,	1,	conversion			#转换
	beq	$t0,	2,	calculation		#计算
	beq	$t0,	3,	exit			#退出
	la	$a0,	error				#没有branch走，说明输入了无效的编码
	li	$v0,	4
	syscall
	j	selection_1

#转进制（Conversin）模块	
conversion:
	la	$a0,	conver_in
	li	$v0,	4
	syscall
	jal	Input1
	move	$s0,	$s5
	j	dec

#计算（Calculation）模块
calculation:
	la	$a0,	selection2
	li	$v0,	4
	syscall
	li	$v0,	5
	syscall
	move	$t0,	$v0
	bgt	$t0,	2,	Error
	blt	$t0,	1,	Error
	jal	Input2
	j	check_0
	
branch_cal:
	beq	$t0,	1,	add
	beq	$t0,	2,	sub

Error:
	la	$a0,	error
	li	$v0,	4
	syscall
	j	calculation


###########################################################
#输入处理模块
Input1:
	li	$v0,	6				#input of a float number
	syscall
	mfc1	$t1,	$f0
	move	$s5,	$t1
	jr	$ra

Input2:
	la	$a0,	num1
	li	$v0,	4
	syscall
	li	$v0,	6
	syscall
	mfc1	$t1,	$f0
	move	$s5,	$t1
	
	la	$a0,	num2
	li	$v0,	4
	syscall
	li	$v0,	6
	syscall
	mfc1	$t1,	$f0
	move	$s6,	$t1
	jr	$ra
										
##########################################
#输出模块
out:
	sll	$s0,	$s0,	31			#符号位移到第31位
	sll	$s1,	$s1,	23			#指数位移到30:23
	add	$s0,	$s0,	$s1			
	lui $t9, 0x007f       
    ori $t9, $t9, 0xffff  
	and $t2, $t2, $t9  	#把最高位除掉
	add	$s0,	$s0,	$s2			#再加尾数

	#十进制输出
dec:
	la	$a0,	dec_out
	li	$v0,	4
	syscall
	addi	$t0,	$s0,	0
	mtc1	$t0,	$f12
	li	$v0,	2
	syscall

	#二进制输出		
bin:
	la	$a0,	bin_out
	li	$v0,	4
	syscall
	#move	$a0,	$s0
	move	$a0, $s0
	li	$v0, 35	#二进制输出
	syscall

	#十六进制输出
hex:
	la	$a0,	hex_out
	li	$v0,	4
	syscall
	move	$a0, $s0
	li	$v0, 34	#十六进制输出
	syscall
	j	selection_1

##########################################
#IEEE 754 标准化  
no_zero:	
	lui $t9, 0x8000       
    ori $t9, $t9, 0x0000 
	and $t1, $t5, $t9    
  	srl  	$t1,	$t1,	31			#得到第一个浮点数的符号位
  	move   	$s0,	$t1
  	
  	lui $t9, 0x7F80       
    ori $t9, $t9, 0x0000 
	and $t1, $t5, $t9   
  	srl  	$t2,	$t1,	23			#得到第一个浮点数的指数位
  	move   	$s1,	$t2
  	
	lui $t9, 0x007f      
    ori $t9, $t9, 0xffff
	and $t1, $t5, $t9	#得到第一个浮点数的尾数位（在前面补1
	move	$s2,	$t1
	lui $t9, 0x0080     
    ori $t9, $t9, 0x0000 
	and $s2, $s2, $t9 
  	
  	addi  	$s3,	$s1,	-127			#得到第一个浮点数Exponent-Bias的值

  	lui $t9, 0x0080     
    ori $t9, $t9, 0x0000 
	and $t1, $t6, $t9    
  	srl  	$t1,	$t1,	31			#得到第二个浮点数的符号位
  	move   	$s4,	$t1
  	
	lui $t9, 0x7f80    
    ori $t9, $t9, 0x0000 
	and $t1, $t6, $t9         
  	srl  	$t3,	$t1,	23			#得到第二个浮点数的指数位
  	move   	$s5,	$t3
 		
	lui $t9, 0x007f    
    ori $t9, $t9, 0xffff
	and $t1, $t6, $t9   	#得到第二个浮点数的尾数位（在前面补1
  	move	$s6,	$t1
  	
	lui $t9, 0x0080    
    ori $t9, $t9, 0x0000
	and $s6, $s6, $t9  
	
	addi	$s7,	$s5,	-127			#得到第二个浮点数Exponent-Bias的值
  	
  	j	match_exp_1


#########################################
# 0操作数检查
check_0:
	move	$t5,	$s5
	move	$t6,	$s6
	j	is_zero

is_zero:
	lui $t9, 0x8000    
    ori $t9, $t9, 0x0000
	and $s1, $zero, $t9 
	or	$t7,	$s5,	$s6
	beq	$t7,	$zero,	res_zero
	beq	$s5,	$zero,	num1_is_zero
	beq	$s6,	$zero,	num2_is_zero
	j	no_zero
	
num1_is_zero:
	beq	$t0,	1,	zero_plus
	blt	$s6,	$zero,	zero_minus_neg
	add	$t7,	$s6,	$s1
	move	$s0,	$t7
	j	dec

zero_minus_neg:
	sub	$t7,	$s6,	$s1
	move	$s0,	$t7
	j	dec

zero_plus:
	move	$s0,	$s6
	j	dec

num2_is_zero:
	move	$s0,	$s5
	j	dec


#########################################
#对阶
match_exp_1:						#对阶 for exponent-bias
	move	$t1,	$s3
	move	$t2,	$s7				#取exponent-bias
	beq	$t1,	$t2,	branch_cal		#指数相等，不用对阶
	blt	$t2,	$t1,	match_exp_2		#如果第一个数的指数更小，则第一个数向第二个数对阶
match_exp_loop1:
	srl	$s2,	$s2,	1			#第一个数的尾数右移
	addi	$t1,	$t1,	1			#第一个数的指数+1
	bne	$t1,	$t2,	match_exp_loop1	#直到两个数的指数相等
	move	$s3,	$s7
	move	$s1,	$s5
	j	branch_cal
	
match_exp_2:						#第二个数的指数更小，则第二个数向第一个数对阶
	move	$t1,	$s3
	move	$t2,	$s7				#取exponent bias
match_exp_loop2:
	srl	$s6,	$s6,	1
	addi	$t2,	$t2,	1
	bne	$t2,	$t1,	match_exp_loop2
	move	$s7,	$s3
	move	$s5,	$s1
	j	branch_cal

#########################################
#运算处理

add:
	beq	$s0,	$s4,	add_same
	blt	$s0,	$s4,	add_pos_neg		#正数+负数
	bgt	$s0,	$s4,	add_neg_pos		#负数+正数
	
add_same:
	add	$s2,	$s2,	$s6
	j	speci
add_pos_neg:
	beq	$s2,	$s6,	res_zero
	blt	$s2,	$s6,	out_neg_1		#小正数+大负数，结果为负
	bgt	$s2,	$s6,	out_pos_1		#大正数+小负数，结果为正
add_neg_pos:
	beq	$s2,	$s6,	res_zero
	blt	$s2,	$s6,	out_pos_2		#小负数+大正数，结果为正
	bgt	$s2,	$s6,	out_neg_2		#大负数+小正数，结果为负

res_zero:
	addi	$s0,	$zero,	0			#结果为0直接跳转输出
	j	dec

out_neg_1:
	addi	$s0,	$zero,	1			#结果的符号位
	sub	$s2,	$s6,	$s2			#尾数用原码表示，可以直接相减得到结果
	j	speci
out_neg_2:
	sub	$s2,	$s2,	$s6
	j	speci
	
out_pos_1:
	sub	$s2,	$s2,	$s6
	j	speci
out_pos_2:
	addi	$s0,	$zero,	0			#结果的符号位
	sub	$s2,	$s6,	$s2
	j	speci

sub:
	beq	$s0,	$s4,	sub_same
	blt	$s0,	$s4,	sub_pos_neg
	bgt	$s0,	$s4,	sub_neg_pos
sub_same:
	beq	$s0,	0,	add_pos_neg		#两个正数相减，相当于一个正数加一个负数
	beq	$s0,	1,	add_neg_pos		#两个负数相减，相当于一个负数加一个正数

sub_pos_neg:
	j	add_same				#一个正数减一个负数，相当于两个正数相加
sub_neg_pos:
	j	add_same				#一个负数减一个正数，相当于两个负数相加

#########################################
#规格化

speci:
   	lui $t9, 0x0080   
    ori $t9, $t9, 0x0000
	and $s5, $zero, $t9 

	lui $t9, 0x0100    
    ori $t9, $t9, 0x0000
	and $s6, $zero, $t9 
	
	bge	$s2,	$s5,	shift_r

shift_l:
	bge	$s2,	$s5,	out			#把最高位的1移到尾数区域外面
	sll	$s2,	$s2,	1
	addi	$s1,	$s1,	-1
	addi	$s3,	$s3,	-1
	j	shift_l
	
shift_r:
	blt	$s2,	$s6,	out			#把最高位的1移到尾数区域的前面
	srl	$s2,	$s2,	1
	addi	$s1,	$s1,	1
	addi	$s3,	$s3,	1
	j	shift_r

exit:
	la	$a0,	end
	li	$v0,	4
	syscall
请说明以上代码