使用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 ...
随机推荐
- Ethical Hacking - GAINING ACCESS(3)
Sever side attacks code execution Let‘s analyze the Zenmap scan result first and search for somethin ...
- javascript : 找到一个树型数据的一个节点及其所有父节点
如题. (function () { let tree = { "id": 0, "label": "all", "childre ...
- 使用SQL语句进行特定值排序
使用SQL语句进行查询时,对数据进行排序,排序要求为排序的一个字段中特定值为顶部呈现: select * from TableName order by case TableFieldName whe ...
- 正在找工作的同学看过来,zozo最新的java面试题总会,学会月薪3万起!!!
引言 为正在找工作的同学提供些许帮助,话不多说直接上题. 关注后私信我[资料]即可免费获取! 关注后私信我[资料]即可免费获取! 关注后私信我[资料]即可免费获取! 关注后私信我[资料]即可免费获取! ...
- c产生随机数(含时间种子)
有时候我们需要程序产生一个随机数. 可以用rand() 但是其实这个随机数是伪随机数,它是一个周期很长的一个值而已. 所以我们可以加入一个随机数种子srand(),这个可以取以当前时间为基准的一个值. ...
- Kali小技巧
说明:此方法适用于Debian.Ubuntu等带apt工具的操作系统. sudo apt-get autoremove --purge 软件名 # 命令&参数解释: # sudo--获取 ro ...
- IPython magic命令
- Django学习路7_注册app到能够在页面上显示app网页内容
在根目录下创建一个 app3 app3 是新 app 的名字 创建一个 urls.py 在 urls.py 中添加 urlpatterns 列表 容纳需要显示在页面上的函数 from django.c ...
- go项目dockerfile最佳实践
1. 前言 2. 不需要cgo情况下的最佳实践 3. 依赖cgo情况下的最佳实践 1. 前言 这几天在构建golang编写的web项目中,关于dockerfile编写的一些总结 可能是单纯我比较菜(大 ...
- Python time localtime()方法
描述 Python time localtime() 函数类似gmtime(),作用是格式化时间戳为本地的时间.高佣联盟 www.cgewang.com 如果sec参数未输入,则以当前时间为转换标准. ...