使用MIPS完成汇编程序——选择排序实现
题目: 从键盘输入10个无符号字数并从大到小进行排序,排序结果在屏幕上显示出来。要求能输入数字 和输出数字 且由大到小来排列
1.代码以及伪代码:
首先写出对应c++代码然后把c++代码翻译成汇编语言
(1)c++代码
#include<iostream>
using namespace std;
//这里使用的是选择排序
int main(){
int a[10];
int max, index;
for (int i = 0; i < 10; i++) {
cin >> a[i]; //输入10个数字
}
for(int i = 0; i < 9; i++) {
max = a[i]; //初始化 max 和 index
index = i;
for(int j = i + 1; j < 10; j++){
if(max < a[j]) {
max = a[j]; //如果a[j]大的话 max易主
index = j;
}
}
a[index] = a[i]; //把扫完一遍后的最大值和a[i]交换,实现最大值被调到前面
a[i] = max;
}
for(int i = 0; i < 10; i++) {
cout << a[i] << " " << endl; //输出
}
}
(2)翻译后的汇编语言以及注释
.text # 代码段 声明
.globl main # globl指明程序的入口地址main
#================================================================================
main: # 程序入口地址
la $a0,input_a_msg # 取字符串首地址
li $v0,4 #4号功能调用,输出字符串
syscall #系统调用,输出字符串
la $t6,arr # $t6 是数组首地址 arr在数据段定义了 分配了10个空间
move $t7,$zero # $t7 是循环变量i 寄存器之间数据的直接交换 把t7变成0 相当于i = 0;
addi $t8,$zero,10 # $t8 是数组长度 t8 = 10 + 0 所以t8 = 10;
move $t9,$zero # $t9 是循环变量j 把t9变成0 相当于j = 0;
#================================================================================
input: # input代码块用于完成数组元素的输入
li $v0,5 # 声明需要调用的操作代码为 5 (read_int) 并赋值给 $v0 这里相当于 cin >> a;
syscall
#==================================================
# t0 = t7
#t0 = t0*4
# t1 = t6 + t0
# 我们得到 t1 = t7 * 4 + t6 此时我们可以认为t1是数组将存元素的地址
# t1 = v0 把刚输入的v0 放到数组中
# SW 把一个字的数据从寄存器存储到存储器中 地址偏移量为0
#==================================================
move $t0,$t7 # 此处类似于C/C++中指针访问数组元素的方法
mul $t0,$t0,4 # 数组元素所占字节数*循环变量+数组的起始地址=数组[循环变量]
addu $t1,$t0,$t6 # '无符号数字相加
sw $v0,0($t1) # ''把$v0的数据存入到$t1中,地址偏移量为0
addi $t7,$t7,1 # t7 = t7 +1 循环变量i自增
blt $t7,$t8,input # 如果t7 小于数组长度(10)的话 也就是还没输入10个数字的话 就仍然进入input 直到输入10个数字后
move $t7,$zero # 完成输入后将循环变量置为0,可作为下一个循环的循环变量,以节省寄存器; $t7作为 i
#==============================================================
loop1: #第一层循环 对每一个 a[i]
# t9 = t7 + 1
# t0 = t7 * 4
# t1 = t0 + t6 由前面两个得到 t1 = 4 * t7 + t6 此时t1 是 数组元素首地址
# 得到数组第0个元素 并且用t2 保存
addu $t9,$t7,1 # 每次执行外层循环都将内层循环的循环变量置为i+1
mul $t0,$t7,4
addu $t1,$t0,$t6 #获取a[i],作为max,即 t2 为max
lw $t2,0($t1) #偏移量,寻址 lw $t2, 0($t0) t0寄存器中的值作为地址, 把这个地址再加上偏移
#量0后 所起始的Word 复制到t2 中 这里t1已经是偏移后的下标了 对他偏移0 就是t1本身的值
#这里我们把他赋值给max 实现代码中的刚进入循环就先把第一个当最大值
move $t5,$t1 #把t5存t1 也就是下标i 进行初始化 这里会直接进入loop2里
#==============================================================
loop2: #代表代码中的 if (max < a[j]){max = a[j]; index = j;}
move $t0,$t9
mul $t0,$t0,4
addu $t4,$t0,$t6 # t4 = t9 * 4 + t6
lw $t3,0($t4) # 此时t3 就是 a[j]的值 t4为 j
bge $t2,$t3,skip # 如果max >= a[j],跳转到skip代码块
lw $t2,0($t4) # 否则就执行下面这两句,赋值 把t2(max) 来保存 a[j]
move $t5,$t4 #t5保存 j的值 t5就是index
#==============================================================
#表示当 max >= a[j]时 跳过loop2 继续判断j的大小
skip:
addi $t9,$t9,1 # 内层循环变量j(t9)自增
blt $t9,$t8,loop2 # 如果j < 10,则跳转到loop2
# 跳出第二层循环
lw $t4,0($t1) # 如果不满足,先进行赋值 t4 表示 a[i]
sw $t4,0($t5) # t4(a[i]) 存到 a[index]里
sw $t2,0($t1) # a[i] 存到 max里
addi $t7,$t7,1 # 再将外层循环的循环变量自增
addi $t4,$t7,1 #且判断是否还满足循环条件
blt $t4,$t8,loop1 # 如果满足,则跳转到loop1
# 如果不满足,则不跳转,继续执行下面的代码
output:
la $a0,output_int_msg # 打印字符串,提示用户即将输出程序
li $v0,4
syscall
move $t7,$zero # 将循环变量置为0,用于下一循环,节省寄存器
print: # 实现打印数组元素
move $t0,$t7
mul $t0,$t0,4
addu $t1,$t0,$t6
lw $a0,0($t1)
li $v0,1
syscall
la $a0,seperate # 分隔数组元素
li $v0,4
syscall
addi $t7,$t7,1
blt $t7,$t8,print # 如果满足循环条件,跳转到print继续执行循环
.data # 数据段声明
arr:.space 10 # 给arr分配10个空间
input_a_msg:.asciiz "Please input 10 abers and use 'Enter' to distinguish every aber\n"
output_int_msg:.asciiz "The result are as follows:\n"
seperate:.asciiz " "
2.汇编程序解释
首先 变量的初始化 对应5~6行
这里我需要 一个数组a 4个变量 i, j,max, index 这里虽然i和j是局部变量,但其实在汇编里面还是需要用一个寄存器来存储的
可以看到用 t6存首地址 t7存 i, t8存长度,t9存j max和index会在后面用到时分给某个寄存器的
其次是数组元素的的输入 对应8~10行
找到数组元素a[i] 是取出地址为 数组首地址 + i * 4
循环的话是用blt 来判断i是否小于10 如果仍小于10的话就回到input模块运行代码
所以循环就是用块 和 逻辑判断语句来实现
第一个循环 14~15行
代码很直白 addu 就是把j变成i+1并且进入下个循环 后面的就是做14~15行
的事情了。
第二循环 17`22行
如果满足max >= a[j]则跳过循环 即进入skip
skip是实现23~24以及外层循环的判断
输出函数 和输入一样 利用循环来实现打印功能
3.用PCSpim运行结果
使用MIPS完成汇编程序——选择排序实现的更多相关文章
- 算法与数据结构(十三) 冒泡排序、插入排序、希尔排序、选择排序(Swift3.0版)
本篇博客中的代码实现依然采用Swift3.0来实现.在前几篇博客连续的介绍了关于查找的相关内容, 大约包括线性数据结构的顺序查找.折半查找.插值查找.Fibonacci查找,还包括数结构的二叉排序树以 ...
- Html5 简单选择排序演示
简单选择排序,是选择排序算法的一种.基本思想:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止.由于在每次循环中,会对数值相等的元素改变位置,所以属于非稳定 ...
- 排序算法总结------选择排序 ---javascript描述
每当面试时避不可少谈论的话题是排序算法,上次面试时被问到写排序算法,然后脑袋一懵不会写,狠狠的被面试官鄙视了一番,问我是不是第一次参加面试,怎么可以连排序算法都不会呢?不过当时确实是第一次去面试,以此 ...
- JavaScript算法(冒泡排序、选择排序与插入排序)
冒泡排序.选择排序与插入排序复杂度都是二次方级别的,放在一起说吧. 介绍一些学习这三个排序方法的比较好的资料.冒泡排序看<学习JavaScript数据结构与算法>介绍的冒泡排序,选择排序看 ...
- 基本排序算法——选择排序java实现
选择排序与冒泡排序有很大的相同点,都是一次遍历结束后能确定一个元素的最终位置,其主要思路是,一次遍历选取最小的元素与第一个元素交换,从而使得一个个元素有序,而后选择第二小的元素与第二个元素交换,知道, ...
- java基础算法之选择排序
选择排序 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完. ...
- 冒泡排序 & 选择排序 & 插入排序 & 希尔排序 JavaScript 实现
之前用 JavaScript 写过 快速排序 和 归并排序,本文聊聊四个基础排序算法.(本文默认排序结果都是从小到大) 冒泡排序 冒泡排序每次循环结束会将最大的元素 "冒泡" 到最 ...
- CPrimerPlus第十一章中的“选择排序算法”学习
C Primer Plus第十一章字符串排序程序11.25中,涉及到“选择排序算法”,这也是找工作笔试或面试可能会遇到的题目,下面谈谈自己的理解. 举个例子:对数组num[5]={3,5,2,1,4} ...
- SelectionSort,选择排序
/**算法:选择排序1,从当前未排序的正数中找一个最小的整数,将它放在已排序的整数列表的最后2.要点:选择排序选最小的,往左边选*/ #include <stdio.h>void Sele ...
随机推荐
- matplotlib常见图表绘制——极坐标图-雷达图、极轴图
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:斑点鱼 极坐标轴 调用subplot()创建子图时通过设置proje ...
- collection集合常用功能
java.util.Collection接口 是所有单列集合最顶层的接口,里面定义了所有单列集合的共性方法 1.public boolean add(E e) 添加元素 2.public bo ...
- vue传参方式
//query传参,使用name跳转 this.$router.push({ name:'second', query: { queryId:'201808 ...
- vue学习(十四) 条件搜索框动态查询表中数据 数组的新方法
//html <div id="app"> <label> 名称搜索关键字: <input type="text" clasa=& ...
- Oracle连接报错之IO异常(The Network Adapter could not establish the connection)
简单介绍:自己封装oracle jdbc的一些常用功能jar包,自己本机玩没啥问题,给别人玩儿,发现总是抛异常 IO异常(The Network Adapter could not establish ...
- 互联网找的e是无理数的初等证明
e的两种计算方式 \(e=lim_{n \to \infty}(1+\frac{1}{n})^n\) \(e=\sum_{n=0}^{+\infty}\frac{1}{n!}\) \(即,e=\fra ...
- php iamp 接收邮件,收取邮件,获取邮件列表
每次想写的时候吧,提笔忘字.等到再次使用,又得想半天,,,,,好尴尬. 这次一边做一边写. 心得,程序员从菜鸟往老鸟转变的重要一步,学英语,看文档,在此我万分感谢鸟哥,,,,没他php哪有官方的中文注 ...
- iOS APP下载安装时,如果出现此时无法下载安装APP的字样时,一些解决思路
1.在iosAPP下载安装时,如果出现此时无法下载安装APP的字样时,可能是苹果系统进行了支持更新,并需要我们确认条约.至于如何判断是否是苹果系统进行了更改,只需要我们进入开发者账号,进入我的账户(A ...
- c++ string 类型 大小写转换
还是用以前的库函数就行的,toupper(int c)小写变大写和tolower(int c)大写变小写 可以直接这么干 string s = "ABCDEFG"; for( in ...
- 第十四章 JDK新特性回顾
14.1.JDK5新特性回顾 自动装箱.拆箱 静态导入 增强for循环 可变参数 枚举 泛型 元数据 14.2.JDK7新特性回顾 对Java集合(Collections)的增强支持 在switch中 ...