zoukankan      html  css  js  c++  java
  • 使用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
    "
    
    output_int_msg:.asciiz "The result are as follows:
    "
    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运行结果

    这里写图片描述

  • 相关阅读:
    .NET连接SAP系统专题:C#如何导入内文至SAP(十一)
    又开始要忙了
    .NET连接SAP系统专题:C#调用BAPI给账户赋予权限(八)
    抉择之苦
    SAP屏幕设计器专题:下拉列表框(四)
    SAP中新建客制表流程
    SAP中使用ABAP远程连接MS Sql Server服务器
    SAP屏幕设计器专题:表格控件(六)
    .NET连接SAP系统专题:C#(NCO3)调用BAPI的一些说明(六)
    SAP屏幕设计器专题:树控件的使用(九)
  • 原文地址:https://www.cnblogs.com/qq874455953/p/9589218.html
Copyright © 2011-2022 走看看