MIPS汇编需求:以半字读取存储无符号短整型输入
MIPS汇编作业:半字变量输入与存储实现方案
作业需求与当前问题
作业要求实现以下功能:
- 定义三个
short(半字)类型变量a、b、c - 提示用户输入三个无符号半字整数(范围0~65535)
- 计算两个公式:
f = 15 * c / b + a % bt = 10 * f / (a - b)
- 以可读格式输出输入值与计算结果
当前已完成程序框架,但未实现半字形式的输入读取与存储,以下是原代码:
## data section .data # 'a'lf I/O a_input_ingerer: .asciiz "please enter a :" a_output_ingerer: .asciiz "a= " # 'b' I/O b_input_ingerer: .asciiz "please enter b :" b_output_ingerer: .asciiz " ,b= " # 'c' I/O c_input_ingerer: .asciiz "please enter c :" c_output_ingerer: .asciiz " ,c=" # outputs f_output_ingerer: .asciiz ",f= " t_output_ingerer: .asciiz "t=" #equations f_equation: .asciiz "\n f = 15 * c / b + a % b\n " t_equation: .asciiz "\n t = 10 * f / (a - b)\n" newline:.asciiz "\n" newline_hastags: .asciiz "\n################\n " newline_tab: .asciiz "\n \t" newline_hastag: .asciiz "\n#" ## error massage error:.asciiz "your number out of range" ############### #code section .text .globl main main: ############################## ## 'a' ##print the String la $a0,a_input_ingerer li $v0,4 syscall ##get the input la $v0,5 syscall ## store the input in register $t1 move $t1,$v0 ######### ## 'b' ##print the String la $a0,b_input_ingerer li $v0,4 syscall ##get the input li $v0,5 syscall ## store the input in register $t2 move $t2,$v0 ######### ## 'a' ##print the String la $a0,c_input_ingerer li $v0,4 syscall ##get the input li $v0,5 syscall ## store the input in register $t3 move $t3,$v0 ######### #calcolation # f=(15*c/b)+(a%b) #(15*c/b) save it at $t4 sll $t4,$t3,0 sll $t5,$t3,1 sll $t6,$t3,2 sll $t7,$t3,3 add $t4,$t5,$t4 add $t4,$t6,$t4 add $t4,$t7,$t4 div $t4,$t2 mflo $t4 #(a%b) div $t1,$t2 mfhi $t5 # (15*c/b)+(a%b) # $t4 + $t5 save it $t4 add $t4,$t5,$t4 ###### # t=10*f/(a-b # 10*f and save it in $t5 sll $t5,$t4,1 sll $t6,$t4,3 add $t5,$t5,$t6 #(a-b)and save it in $t6 sub $t6,$t1,$t2 # 10*f / (a-b) and save it in $t5 # $t5 / $t6 div $t5,$t6 mflo $t5 ########################## #Output #first equation input la $a0, a_output_ingerer li $v0,4 syscall move $a0,$t1 li $v0,1 syscall la $a0,b_output_ingerer li $v0,4 syscall move $a0,$t2 li $v0,1 syscall la $a0,c_output_ingerer li $v0,4 syscall move $a0,$t3 li $v0,1 syscall ##first equation la $a0,f_equation li $v0,4 syscall #first equation result la $a0,f_output_ingerer li $v0,4 syscall move $a0,$t4 li $v0,1 syscall ############################### la $a0,newline_hastags li $v0,4 syscall #second equation input la $a0, a_output_ingerer li $v0,4 syscall move $a0,$t1 li $v0,1 syscall la $a0,b_output_ingerer li $v0,4 syscall move $a0,$t2 li $v0,1 syscall la $a0,f_output_ingerer li $v0,4 syscall move $a0,$t4 li $v0,1 syscall ##second equation la $a0,t_equation li $v0,4 syscall #second equation result la $a0,t_output_ingerer li $v0,4 syscall move $a0,$t5 li $v0,1 syscall ####################################### #system call for termainating the exeuction li $v0,10 syscall
修改方案与完整代码
修改要点
- 定义半字变量:在
.data段添加半字类型的存储单元 - 输入校验与存储:读取整数后校验范围,符合要求用
sh指令存入半字变量 - 无符号半字加载:用
lhu指令加载变量,保留无符号属性 - 边界错误处理:添加除零检查,避免运行时崩溃
修改后的完整代码
## data section .data # 半字变量定义 a: .half 0 b: .half 0 c: .half 0 # 'a' I/O a_input_integer: .asciiz "please enter a :" a_output_integer: .asciiz "a= " # 'b' I/O b_input_integer: .asciiz "please enter b :" b_output_integer: .asciiz " ,b= " # 'c' I/O c_input_integer: .asciiz "please enter c :" c_output_integer: .asciiz " ,c=" # outputs f_output_integer: .asciiz ",f= " t_output_integer: .asciiz "t=" # equations f_equation: .asciiz "\n f = 15 * c / b + a % b\n " t_equation: .asciiz "\n t = 10 * f / (a - b)\n" newline:.asciiz "\n" newline_hastags: .asciiz "\n################\n " ## error messages error_range:.asciiz "Error: number out of unsigned half-word range (0~65535)\n" error_div_zero:.asciiz "Error: division by zero\n" ############### # code section .text .globl main main: ############################## ## 读取并存储a # 提示输入 la $a0, a_input_integer li $v0, 4 syscall # 读取整数 li $v0, 5 syscall # 校验范围:无符号半字最大为65535 li $t0, 65535 bgt $v0, $t0, out_of_range blt $v0, $zero, out_of_range # 无符号数不能为负 # 存储到半字变量a sh $v0, a ######### ## 读取并存储b # 提示输入 la $a0, b_input_integer li $v0, 4 syscall # 读取整数 li $v0, 5 syscall # 校验范围 bgt $v0, $t0, out_of_range blt $v0, $zero, out_of_range # 检查b是否为0 beq $v0, $zero, div_by_zero # 存储到半字变量b sh $v0, b ######### ## 读取并存储c # 提示输入 la $a0, c_input_integer li $v0, 4 syscall # 读取整数 li $v0, 5 syscall # 校验范围 bgt $v0, $t0, out_of_range blt $v0, $zero, out_of_range # 存储到半字变量c sh $v0, c ######### # 加载半字变量到寄存器(无符号加载lhu) lhu $t1, a lhu $t2, b lhu $t3, c # 计算f = 15*c/b + a%b # 计算15*c:15=8+4+2+1,用移位加法实现 sll $t4, $t3, 3 # 8*c sll $t5, $t3, 2 #4*c sll $t6, $t3, 1 #2*c add $t4, $t4, $t5 #8c+4c=12c add $t4, $t4, $t6 #12c+2c=14c add $t4, $t4, $t3 #14c+c=15c # 15c / b,结果存$t4 div $t4, $t2 mflo $t4 # a%b,结果存$t5 div $t1, $t2 mfhi $t5 # f = 15c/b + a%b,结果存$t4 add $t4, $t4, $t5 ###### # 计算t = 10*f/(a-b) # 计算10*f:10=8+2 sll $t5, $t4, 3 #8*f sll $t6, $t4, 1 #2*f add $t5, $t5, $t6 #8f+2f=10f # 计算a-b,存$t6 sub $t6, $t1, $t2 # 检查除数是否为0 beq $t6, $zero, div_by_zero # 10f/(a-b),结果存$t5 div $t5, $t6 mflo $t5 ########################## # 输出部分 # 输出输入值 la $a0, a_output_integer li $v0,4 syscall move $a0,$t1 li $v0,1 syscall la $a0,b_output_integer li $v0,4 syscall move $a0,$t2 li $v0,1 syscall la $a0,c_output_integer li $v0,4 syscall move $a0,$t3 li $v0,1 syscall # 输出f的公式与结果 la $a0,f_equation li $v0,4 syscall la $a0,f_output_integer li $v0,4 syscall move $a0,$t4 li $v0,1 syscall ############################### la $a0,newline_hastags li $v0,4 syscall # 输出t的输入依赖与公式 la $a0, a_output_integer li $v0,4 syscall move $a0,$t1 li $v0,1 syscall la $a0,b_output_integer li $v0,4 syscall move $a0,$t2 li $v0,1 syscall la $a0,f_output_integer li $v0,4 syscall move $a0,$t4 li $v0,1 syscall la $a0,t_equation li $v0,4 syscall # 输出t的结果 la $a0,t_output_integer li $v0,4 syscall move $a0,$t5 li $v0,1 syscall # 正常退出 li $v0,10 syscall # 错误处理分支 out_of_range: la $a0, error_range li $v0,4 syscall li $v0,10 syscall div_by_zero: la $a0, error_div_zero li $v0,4 syscall li $v0,10 syscall
修改细节说明
- 半字变量定义:用
.half指令分配2字节存储单元,符合short类型要求 - 输入校验:确保输入值在0~65535范围内,不符合则输出错误并退出
- 半字操作:用
sh(存储半字)和lhu(无符号加载半字)指令,保证数据以半字形式存储且保留无符号属性 - 除零检查:对b=0和a-b=0的情况做判断,避免运行时除法错误
内容的提问来源于stack exchange,提问作者محمد العر</think_never_used_51bce0c785ca2f68081bfa7d91973934>
相关产品推荐
相关产品推荐

