使用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中,地址偏移量为0addi $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+1mul $t0,$t7,4 addu $t1,$t0,$t6 #获取a[i],作为max,即 t2 为maxlw $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 + t6lw $t3,0($t4) # 此时t3 就是 a[j]的值 t4为 jbge $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,4syscallmove $t7,$zero # 将循环变量置为0,用于下一循环,节省寄存器print: # 实现打印数组元素move $t0,$t7mul $t0,$t0,4addu $t1,$t0,$t6lw $a0,0($t1)li $v0,1syscallla $a0,seperate # 分隔数组元素li $v0,4syscalladdi $t7,$t7,1blt $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完成汇编程序——选择排序实现相关推荐
- 算法图解/二分查找/简单查找/选择排序/递归算法/快速排序算法/
大 O 表示法 大 O 表示法在讨论运行时间时,log 指的都是 log2 大 O 表示法指出了算法有多快,让你能够比较操作数,它指出了算法运行时间的增速,而并非以秒为单位的速度. 大 O 表示法指出 ...
- 交换排序图解_图解简单选择排序
简单选择排序 有如下数组,我们需要对它从小到大排序,步骤如下: 在数组中找到最小值,然后与第一个位置交换. 除去第一个位置在数组中继续找最小值,与第二个位置交换,以此类推,直到末尾. 下图展示了整个交 ...
- 经典算法学习——直接选择排序
直接选择排序和直接插入排序相似,都将数据分为有序区和无序区,所不同的是直接插入排序是将无序区的第一个元素直接插入到有序区以形成一个更大的有序区.而直接选择排序是从无序区选一个最小的元素直接放到有序区的 ...
- 排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序...
先推荐一篇关于排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html 本文思路部分来源于上篇文章,但测得的结果似乎 ...
- 8)排序②排序算法之选择排序[1]直接选择排序
1 #include<iostream> 2 using namespace std; 3 4 //*******直接选择排序********* 5 int select_sort(int ...
- 三种基本排序的实现及其效率对比:冒泡排序、选择排序和插入排序
1 public class ThreeTypesOfBaseSort { 2 // ========================== 三种基本排序的效率对比 ================== ...
- 【算法导论】冒泡排序 选择排序
冒泡排序: //从大到小 void bubble_sort(int array[],int len) {int i,j,t;for(i=0;i<len-1;i++){for(j=0;j<l ...
- 链表问题16——单链表的选择排序(python版本)
题目 给定一个无序单链表头节点head,实现单链表的选择排序 要求:额外空间复杂度为O(1),时间复杂度O() 思路 选择排序是从未排序的部分中找到最小值,然后放在排好序部分的尾部. 开始整个链表都是 ...
- 链表问题16——单链表的选择排序
题目 给定一个无序单链表头节点head,实现单链表的选择排序 要求:额外空间复杂度为O(1),时间复杂度O() 思路 选择排序是从未排序的部分中找到最小值,然后放在排好序部分的尾部. 开始整个链表都是 ...
- 【Java常识】7.0 数组实现冒泡排序、选择排序和二分查找
1.0 冒泡排序原理 冒泡排序就是:轻的上浮,沉的下降.小的往前排,大的往后走. 原理:若一个N个元素的数组,两个相邻位置比较,如果前面的元素比后面的元素大就换位置. 每一次比较,都是相对最沉的到位. ...
最新文章
- Spring MVC 返回视图时添加的模型数据------POJO
- 前端学习(2685):重读vue电商网站6之如何重置表单
- 互联网日报 | 微信支付启动“8.8智慧生活日”;抖音企业号数量突破400万;苏宁将布局车联网领域...
- c 窗体中添加mysql控件,MYSQL 统计数据-svn服务器启动-WinFrom控件库|.net开源控件库|HZHControls官网...
- 死锁必要条件、解决死锁策略
- 【Java数据结构与算法】第十二章 哈夫曼树和哈夫曼编码
- java web前端邮件,javaweb之javamail
- 剑指offer面试题[12]-打印1到最大的n位数
- LeetCode OJ:Linked List Cycle(链表循环)
- 【车间调度】基于matlab模拟退火算法求解车间调度问题【含Matlab源码 894期】
- CPDA数据分析师:一个完整的数据分析流程
- Python压缩图片到指定大小
- 关于CASS点自动连线方法
- 全球及中国飞行时间传感器芯片行业研究及十四五规划分析报告
- Javascript 格式化json字符串
- 性能优化之内存泄露(Memory Leak)常用分析工具(另3种)
- ajax技术的实质是什么意思,什么是Ajax?Ajax的原理是什么?Ajax的核心技术是什么?Ajax的优缺点是什么?...
- SQL高级教程(三十)- - SQL NULL 函数
- tcl/tk参考——列表操作llength
- html 前端优化上传视频,前端上传组件Plupload使用---上传大视频(分片上传)