题目: 从键盘输入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完成汇编程序——选择排序实现的更多相关文章

  1. 算法与数据结构(十三) 冒泡排序、插入排序、希尔排序、选择排序(Swift3.0版)

    本篇博客中的代码实现依然采用Swift3.0来实现.在前几篇博客连续的介绍了关于查找的相关内容, 大约包括线性数据结构的顺序查找.折半查找.插值查找.Fibonacci查找,还包括数结构的二叉排序树以 ...

  2. Html5 简单选择排序演示

    简单选择排序,是选择排序算法的一种.基本思想:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止.由于在每次循环中,会对数值相等的元素改变位置,所以属于非稳定 ...

  3. 排序算法总结------选择排序 ---javascript描述

    每当面试时避不可少谈论的话题是排序算法,上次面试时被问到写排序算法,然后脑袋一懵不会写,狠狠的被面试官鄙视了一番,问我是不是第一次参加面试,怎么可以连排序算法都不会呢?不过当时确实是第一次去面试,以此 ...

  4. JavaScript算法(冒泡排序、选择排序与插入排序)

    冒泡排序.选择排序与插入排序复杂度都是二次方级别的,放在一起说吧. 介绍一些学习这三个排序方法的比较好的资料.冒泡排序看<学习JavaScript数据结构与算法>介绍的冒泡排序,选择排序看 ...

  5. 基本排序算法——选择排序java实现

    选择排序与冒泡排序有很大的相同点,都是一次遍历结束后能确定一个元素的最终位置,其主要思路是,一次遍历选取最小的元素与第一个元素交换,从而使得一个个元素有序,而后选择第二小的元素与第二个元素交换,知道, ...

  6. java基础算法之选择排序

    选择排序 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完. ...

  7. 冒泡排序 & 选择排序 & 插入排序 & 希尔排序 JavaScript 实现

    之前用 JavaScript 写过 快速排序 和 归并排序,本文聊聊四个基础排序算法.(本文默认排序结果都是从小到大) 冒泡排序 冒泡排序每次循环结束会将最大的元素 "冒泡" 到最 ...

  8. CPrimerPlus第十一章中的“选择排序算法”学习

    C Primer Plus第十一章字符串排序程序11.25中,涉及到“选择排序算法”,这也是找工作笔试或面试可能会遇到的题目,下面谈谈自己的理解. 举个例子:对数组num[5]={3,5,2,1,4} ...

  9. SelectionSort,选择排序

    /**算法:选择排序1,从当前未排序的正数中找一个最小的整数,将它放在已排序的整数列表的最后2.要点:选择排序选最小的,往左边选*/ #include <stdio.h>void Sele ...

随机推荐

  1. 深入掌握K8S Pod

    k8s系列文章: 什么是K8S K8S configmap介绍 Pod是k8s中最小的调度单元,包含了一个"根容器"和其它用户业务容器. 如果你使用过k8s的话,当然会了解pod的 ...

  2. git chechout

    在克隆完一个的版本库时,git会在本地创建一个master分支用于跟踪远端的master分支 如git clone abc.git 默认情况下git会在本地创建一个master分支 但是,在本地mas ...

  3. matplotlib图表介绍

    Matplotlib 是一个python 的绘图库,主要用于生成2D图表. 常用到的是matplotlib中的pyplot,导入方式import matplotlib.pyplot as plt 一. ...

  4. pandas处理excel文件和csv文件

    一.csv文件 csv以纯文本形式存储表格数据 pd.read_csv('文件名'),可添加参数engine='python',encoding='gbk' 一般来说,windows系统的默认编码为g ...

  5. Android实现EditText插入表情、超链接等格式

    参考:https://www.jianshu.com/p/84067ad289d2 参考:https://www.jianshu.com/p/d82ac2edc7e8

  6. Spring main方法中怎么调用Dao层和Service层的方法

    在web环境中,一般serviceImpl中的dao之类的数据库连接都由容器启动的时候创建好了,不会报错.但是在main中,没有这个环境,所以需要获取环境: ApplicationContext ct ...

  7. Android中Fragment生命周期和基本用法

    1.基本概念 1. Fragment是什么? Fragment是可以让你的app纵享丝滑的设计,如果你的app想在现在基础上性能大幅度提高,并且占用内存降低,同样的界面Activity占用内存比Fra ...

  8. excel文件双击打开空白

    excel文件双击打开之后进入软件,没有去读文件 一.现象描述 打开现象如下所示,只有excel模板,看不到excel中的表格模板. 二.想要打开文件 (1)在软件的文件--->打开--> ...

  9. PHP is_writable() 函数

    定义和用法 is_writable() 函数检查指定的文件是否可写. 如果文件可写,该函数返回 TRUE. 语法 is_writable(file) 参数 描述 file 必需.规定要检查的文件. 提 ...

  10. mysql中走与不走索引的情况汇集(待全量实验)

    说明 在MySQL中,并不是你建立了索引,并且你在SQL中使用到了该列,MySQL就肯定会使用到那些索引的,有一些情况很可能在你不知不觉中,你就“成功的避开了”MySQL的所有索引. 索引列参与计算 ...