下面是一个 MIPS 汇编程序,实现了上述要求。该程序首先提示用户输入数字串,然后将输入的数字串转换为多个数值,并存入变量缓冲区中。之后使用冒泡排序对这些数字进行排序(递减),最后将排序后的结果以十进制显示出来。
.data
input_prompt: .asciiz "Input Numbers: "
output_prompt: .asciiz "\nSorted Numbers: "
error_prompt: .asciiz "Error: Invalid Input!\n"
buffer: .space 1000 # 缓冲区,用于存储输入的数字串
sorted: .space 1000 # 缓冲区,用于存储排序后的结果
.text
main:
la $a0, input_prompt # 提示用户输入数字串
li $v0, 4
syscall
la $a0, buffer # 读入数字串
li $a1, 1000
li $v0, 8
syscall
jal convert_input_to_numbers # 将数字串转换为多个数值,并存入变量缓冲区
jal bubble_sort # 对数字进行冒泡排序
la $a0, output_prompt # 显示排序后的结果
li $v0, 4
syscall
jal output_sorted_numbers # 输出排序后的结果
li $v0, 10 # 退出程序
syscall
# 将数字串转换为多个数值,并存入变量缓冲区
convert_input_to_numbers:
li $t0, 0 # $t0 用于记录数字串中的数字个数
li $t1, 0 # $t1 用于计算每一个数字的值
la $t2, buffer # $t2 指向数字串的起始地址
loop:
lbu $t3, ($t2) # 取出数字串中的一个字符
beqz $t3, exit_convert # 判断是否到了字符串结尾
addi $t2, $t2, 1 # 指向下一个字符
bltu $t3, 48, error # 如果字符不是数字、空格或减号,就跳转到错误处理
bgtu $t3, 57, error
bne $t3, 32, read_digit # 如果字符不是空格,就直接读取数字
beq $t1, $zero, loop # 如果当前还没有读取到数字,就继续循环
sw $t1, ($sp) # 将当前读取的数字存入变量缓冲区
addiu $sp, $sp, -4 # 更新栈指针,使其指向下一个位置
li $t1, 0 # 将 $t1 清零,等待下一次读取数字
addi $t0, $t0, 1 # 数字个数加一
j loop # 继续循环
read_digit:
subi $t3, $t3, 48 # 将字符转化为数字
mul $t1, $t1, 10 # 将当前读取的数字乘以 10
add $t1, $t1, $t3 # 加上当前读取的数字
j loop
error:
la $a0, error_prompt # 显示错误提示信息
li $v0, 4
syscall
exit_convert:
sw $t0, ($sp) # 将数字个数存入变量缓冲区
addiu $sp, $sp, -4 # 更新栈指针,使其指向下一个位置
jr $ra
# 对数字进行冒泡排序(递减)
bubble_sort:
lw $t0, ($sp) # 从变量缓冲区中读取数字个数
addi $sp, $sp, 4 # 更新栈指针
la $t1, buffer # $t1 指向数字缓冲区的起始地址
la $t2, sorted # $t2 指向排序后的结果缓冲区的起始地址
li $t3, 0 # $t3 用于标记是否进行了交换
outer_loop:
li $t4, 1 # $t4 用于记录当前循环的最大位置
inner_loop:
lw
�
5
,
(
t5,(t1) # 取出相邻两个数字
lw
�
6
,
4
(
t6,4(t1)
ble $t5, $t6, no_swap # 如果前一个数字比后一个数字小或等于,就不需要进行交换
sw
�
6
,
(
t6,(t1) # 进行交换
sw
�
5
,
4
(
t5,4(t1)
li $t3, 1 # 标记进行了交换
no_swap:
addi $t1, $t1, 4 # 指向下一个数字
bltu $t1, $t2, inner_loop # 如果还没有遍历到最后一个数字,就继续循环
sub $t4, $t4, 1 # 最大位置减一
bltu $t4, $zero, exit_sort # 如果已经遍历到第一个数字,排序完成
addi $t1, $t2, -4 # 指向倒数第二个数字
move $t3, $zero # 将标记清零
bltu $t0, $t4, outer_loop # 如果还没有遍历到最大位置,就继续循环
exit_sort:
jr $ra
输出排序后的结果
output_sorted_numbers:
lw
�
0
,
(
t0,(sp) # 从变量缓冲区中读取数字个数
addi $sp, $sp, 4 # 更新栈指针
la $t1, sorted # $t1 指向排序后的结果缓冲区的起始地址
loop:
lw
�
2
,
(
t2,(t1) # 取出一个数字
li $v0, 1 # 将数字以十进制显示出来
move $a0, $t2
syscall
li $v0, 4 # 显示空格
la $a0, " "
syscall
addi $t1, $t1, 4 # 指向下一个数字
subi $t0, $t0, 1 # 数字个数减一
bgtz $t0, loop # 如果还没有输出完所有数字,就继续循环
jr $ra
请注意,该程序对输入的数字串进行了简单的格式检查。如果发现输入的数字串中有非数字、非空格和非减号的字符,程序将输出错误提示信息并退出。
此外,程序使用了两个缓冲区:buffer
用于存储输入的数字串,sorted
用于存储排序后的结果。在程序的不同阶段,这两个缓冲区的内容会被多次修改,请务必小心操作。