ECOP——MIPS汇编语言实现冒泡排序

/* 简单说明:这是计算机组成与设计实验课的第一次实验,与理论课上学的MIPS语法比较对口,算是一次实战。写在这里是为了记录、备份以及巩固。以下内容有部分是参考自其他网站。*/

一.实验目的

1.认识和掌握MIPS汇编语言程序设计的基本方法。
2 熟悉PCSpim模拟器的使用。

二.实验内容

从键盘输入10个无符号字数并从大到小进行排序,排序结果在屏幕上显示出来。

三.实验器材

电脑一台、PCSpim模拟器软件一套。

四.实验过程

1)设计流程图:

这里写图片描述

2)代码实现:


#C++代码

###################################################################
#   // 从键盘输入10个无符号字数并从大到小进行排序,排序结果在屏幕上显示出来
#   #include <iostream>
#   using namespace std;
#   int main() {
#       int array[10];
#       for (int i = 0; i < 10; i++)
#           cin >> array[i];
#       for (int i = 0; i < 9; i++) {
#           for (int j = 0; j < 9-i; j++) {
#               if (array[j] < array[j+1]) {
#                   int temp = array[j];
#                   array[j] = array[j+1];
#                   array[j+1] = temp;
#               }
#           }
#       }
#       for (int i = 0; i < num; i++)
#           cout << array[i] << ' ';
#       return 0;
#   }
###################################################################

                            # MIPS汇编语言代码
.text                       # 代码段以 .text 为开始标志,即各项指令操作
.globl main                 # 定义 main 为外部程序可以访问的标签
main:                       # 程序入口
    li $v0, 4				# 操作码$v0 = 4, 将要打印的字符串赋给 $a0
    la $a0, input_msg;     # la(load address), 打印字符串,提示用户输入排序数组长度
    syscall                 # 调用操作系统完成打印(输出)

    la $t6, array			# $t6 为数组首地址
    move $t7, $zero          # $t7 为循环变量i, i = 0
    move $t8, $zero          # $t8 为数组长度
    addi $t8, $t8, 10        # $t8 = 10 
    move $t9, $zero          # $t9 是循环变量j, j = 0


input:                      # input代码块用于完成数组元素的读入
    li $v0, 5				# 操作码$v0 = 5, 将读取的整型赋值给$v0, cin >> $t0
    syscall                 
                            # array[i] = $t0
    move $t0, $t7            # 此处类似C/C++中指针访问数组元素的方法
    mul $t0, $t0, 4          # 此处第二个$t0表示的应该是下标
    addu $t1, $t0, $t6		# $t1为需要访问的元素的地址
    sw $v0, 0($t1)            # 将下标对应的值存到$v0

    addi $t7, $t7, 1        # i++
    blt $t7, $t8, input     # if i < 10, jump to input  
    move $t7, $zero         # 输入结束,将循环变量$t7置为0,节省寄存器


loop1:                      # 此为外层循环,将内层循环的变量置为0,
    move $t9, $zero         # j = 0
loop2:
                            # 获取 array[j]
    move $t0, $t9           # $t0 = $t9 = j
    mul $t0, $t0, 4         # $t0 = array[j]与array[0]的地址差
    addu $t1, $t0, $t6		# $t1 = array[j]
    lw $t2, 0($t1)            # 将 arrat[j] 放入寄存器$t2中

                            # 获取 array[j+1]
    addi $t0, $t9, 1        # j++
    mul $t0, $t0, 4         # $t0 = 4 * j
    addu $t4, $t0, $t6		# $t4 = array + 4*j, 即 $t4 = array[j]
    lw $t3, 0($t4)            # $t3 = array[j]

    bge $t2, $t3, continue  # if (a[j] >= a[j+1]) jump to the continue module
    sw $t3, 0($t1)            # else 
    sw $t2, 0($t4)            # exchange a[j] with a[j+1]


continue:
                            # continue the "for" loop
                            # 实现 j < 10-i-1; j++
    addi $t9, $t9, 1        # j++
    move $t0, $t9           # $t0 = j
    sub $t1, $t8, $t7 		# $t1 = $t8 - i = 10 - i
    sub $t1, $t1, 1         # $t1 = $t1 - 1 = 10 - i - 1
    blt $t0, $t1, loop2     # if j < 10-i-1, jump to loop2
                            # 实现 i < 10-1; i++
    addi $t7, $t7, 1        # i++   
    sub $t2, $t8, 1         # $t2 = $t8 - 1 = 10 - 1
    blt $t7, $t2, loop1     # if i < 10 - 1, jump to loop1

output:
    li $v0, 4				# 操作码$v0 = 4, 将要打印的字符串赋给 $a0
    la $a0, output_msg         # 打印字符串,提示用户即将输出程序
    syscall

    move $t7, $zero         # 将变量置为0,用于下一循环,节省寄存器

print:
                            # 打印数组元素
    move $t0, $t7           # $t0 = i  
    mul $t0, $t0, 4         # $t0 = 4 * i
    addu $t1, $t0, $t6		# $t1 = array + 4*i, 即 $t1 = array[i]
    li $v0, 1				# 操作码$v0 = 1, 将要打印的字整型赋给 $a0
    lw $a0, 0($t1)
    syscall

    li $v0, 4 				# 操作码$v0 = 4, 将要打印的字符串赋给 $a0
    la $a0, space          # 打印空格,分隔数组元素
    syscall

    addi $t7, $t7, 1        # i++
    blt $t7, $t8, print     # if i < 10, jump to print


.data                       # 数据声明,数据段以.data为开始标志
array:.space 1024           # .space指明空间大小, 单位为 bytes
input_msg:.asciiz "Please enter 10 numbers to be sorted, each number a single line:\n"
output_msg:.asciiz "The sorted numbers are:\n"
space:.asciiz " "           
                            # 用双引号包含字符串
                            # 变量名后留冒号:
                            # .asciiz会在字符串最后加上一个终止符,类似C中的'\0', 而.ascii则不会



五.实验结果

Please enter 10 numbers to be sorted, each number a single line:
1
0
2
9
3
8
4
7
5
6
The sorted numbers are:
9 8 7 6 5 4 3 2 1 0


参考和学习了以下网站:
MIPS汇编:冒泡排序
计算机组成原理之MIPS汇编:冒泡排序
【十分钟教会你汇编】MIPS编程入门


猜你喜欢

转载自blog.csdn.net/ill__world/article/details/78307796
今日推荐