实验内容

从键盘输入10个无符号字数并从大到小进行排序,排序结果在屏幕上显示出来。

实验步骤

设计遵循以下步骤:①C语言设计

②单元代码转写及变量映射

③单元伪汇编设计

④单元测试及debug

⑤回到步骤①,直到程序完成

代码设计

整个程序可以分为三个单元:读入读入单元,排序单元,输出单元。由于各单元的设计方法,下面以读入单元为例展开叙述。

1.首先我们进行C语言设计//read in

int arr[10];

for (int i =0; i <10; i++) {

scanf("%d", &arr[i]);

}

可以看到,读入单元十分简单,一个for循环,然后读入数据到arr[i]就好了。

2.变量映射及代码转写

变量映射,就是把涉及到的变量对应为寄存器。代码转写,就是把其中的循环,及分支判断用goto转写成顺序结构语句,虽然实际运行的时候是有循环的。

各个涉及变量映射到对应寄存器,如表1所示。

而对于上一个步骤的C代码,我们可以如下转写:申请空间,基准地址为arr,长度为10 int,即4 word

int i = 0;

Loop:

偏移量bias = i * 4;

实际地址 addr = arr + bias;

读入数据到 tmp;

arr[addr] = tmp;

i = i + 1;

if (i < 10) goto Loop;

3.单元伪代码设计

3.单元伪汇编设计

根据上一步骤的伪代码转写和变量映射,我们查询相关的MIPS指令集和系统调用后,可以写出以下MIPS指令。li $v0, 9 #9号syscall,请求内存空间

li $a0, 40 #申请40byte,4word的空间大小

syscall #系统调用

add $s1, $v0, $zero #加载基准内存地址

add $s0, $zero, $zero # $s0 就是 int i

read:

#读数开始

li $v0, 5 #从键盘读整数

syscall #系统调用,读到$v0中

sll $t0, $s0, 2 #偏移量 $t0 =i*4

add $t1, $t0, $s1 #$t1 实际地址 = 偏移量$t0 + 基准地址

sw $v0, 0($t1) #写入到实际地址 $t1

#读数结束

addi $s0, $s0, 1 #i = i + 1

slti $t0, $s0, 10 #若i<10

bne $t0, $zero, read #则继续循环

4.单元测试与debug

单元测试就是根据我们写出来的单元,输入数据,运行程序,观察输出结果是否与预期一致,如一致则说明MIPS代码正确;否则,单步执行,观察寄存器变量与预期不符的代码行,对该行代码进行检查及修改。

如图4所示,我们开始运行程序,并输入10个数字。

观察DATA区,如图5,发现内存存的数与我们输入的一致,说明该单元没有问题。

5.完成其他模块,组合成最终程序

同样的道理,我们可以对其他的单元进行设计、实现、测试。完成所有模块并测试debug完成后,最终运行结果如图6.

完整代码如下:#**************************

#从键盘读入数据、排序并输出

#**************************

.text #代码段

.globl main #程序从此开始

main: #主程序

li $v0, 9 #9号syscall,请求内存空间

li $a0, 40 #申请40byte,4word的空间大小

syscall #系统调用

add $s1, $v0, $zero #加载基准内存地址

add $s0, $zero, $zero # $s0 就是 int i

read:

#读数开始

li $v0, 5 #从键盘读整数

syscall #系统调用,读到$v0中

sll $t0, $s0, 2 #偏移量 $t0 =i*4

add $t1, $t0, $s1 #$t1 实际地址 = 偏移量$t0 + 基准地址

sw $v0, 0($t1) #写入到实际地址 $t1

#读数结束

addi $s0, $s0, 1 #i = i + 1

slti $t0, $s0, 10 #若i<10

bne $t0, $zero, read #则继续循环

sort:

add $s0, $zero, $zero # $s0 就是 int i = 0

oLop:

#外层循环开始

addi $s2, $zero, 9 #$s2 就是 int j = 9

iLop:

#内层循环开始

sll $t0, $s2, 2 #偏移量j*4

add $t1, $s1, $t0 #A[j]的实际内存地址

addi $t2, $t1, -4 #A[j-1]的实际内存地址

lw $t3, 0($t1) #$t3=A[j]的值

lw $t4, 0($t2) #$t4=A[j-1]的值

slt $t5, $t4, $t3 #若A[j-1] < A[j]

beq $t5, $zero, afterSwap #为真交换,否则跳过

#swap

lw $t6, 0($t1) # tmp=A[j]

sw $t4, 0($t1) # A[j] = A[j-1]

sw $t6, 0($t2) # A[j-1]=tmp

afterSwap:

addi $s2, $s2, -1 # j = j - 1

slt $t0, $s0, $s2 #若i < j

bne $t0, $zero, iLop #继续内层循环

addi $s0, $s0, 1 # i = i + 1

slti $t0, $s0, 9 #若i<9

bne $t0, $zero, oLop #则继续外层循环

#外层循环结束

#print

#基准地址是$s1

add $s0, $zero, $zero # $s0 就是 int i

print: # 输出开始

li $v0, 1 #置输出int函数ID

sll $t0, $s0, 2 #偏移量 $t0 =i*4

add $t1, $t0, $s1 #$t1 实际地址 = 偏移量$t0 + 基准地址

lw $a0, 0($t1) #写入输出参数到 $a0

syscall #系统调用,输出排序后整数

li $v0, 11 #置输出char函数ID

add $a0, $zero, 32 #置输出参数: 空格

syscall #输出空格

addi $s0, $s0, 1 #i = i + 1

slti $t0, $s0, 10 #若i<10

bne $t0, $zero, print #则继续循环

li $v0, 10 #停

syscall #机

实验心得

1.查阅文档,忌臆想

在写出伪代码转写后,我需要对应的伪汇编指令及系统调用来实现,但是我不知道这些指令,以及他们的用法。我开始尝试看着示例尝试性地打,发现频频出错,甚至有时语法检查都不通过。做了许多无用功后开始反思,去查指令集,看课本对指令的说明解析,包括参数的含义及写法。

2.清晰的设计实现流程:C代码-伪代码转写-伪汇编-测试及修正

一开始不知道如何想,因为汇编代码不像C那样有着清晰的循环,分支结构,反而是指令的顺序排列,这并不易读不易想。遵循上述设计流程,则将任务分化了,写伪汇报时只要照着伪代码打就好了。

3.模块化设计

C语言中,循环语句和循环块是可以分离的。同样的道理,在对应的伪汇编中,循环语句和循环块也可以分离。这样,我们在输入单元中成功设计了一个循环,只要将循环语句提取出来,两个嵌套,便可得到排序单元中的双重循环框架。这样,在排序单元中,我们便避免了对双重循环的重新设计。

4.注释

注释具有十分重要作用,可以说明个个寄存器的作用,设计时减少了记忆负担。可以注释每一条MIPS指令的作用,debug时可以通过检查注释与MIPS指令是否一致来排查错误。

c语言写成汇编语言程序 冒泡排序,MIPS汇编程序设计——冒泡排序相关推荐

  1. 语言翻译成汇编语言_学习编程有没有必要从C语言和C++学起?应该怎么学?

    硬件层级:这里也就是实体硬件,包括:CPU.内存.显卡等等...这些都不属于软件的范畴内. 汇编层级:在之前没有C/C++以及java之前,是汇编的年代.那么汇编语言对于我们来说,可读性是很查的,不适 ...

  2. mapreduce编程实例python-使用Python语言写Hadoop MapReduce程序

    原标题:使用Python语言写Hadoop MapReduce程序 Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 在本教程中,我将描述如何使用Pytho ...

  3. 简单介绍三个C语言图形库C语言其实最擅长的是写纯数据处理的程序 . 非得用C语言写个界面程序那将会变得很困难 . 我刚开始学C语言就是从hello world 开始的 , 后来慢慢开始学从三个数中找

    C语言其实最擅长的是写纯数据处理的程序 . 非得用C语言写个界面程序那将会变得很困难 . 我刚开始学C语言就是从hello world 开始的 , 后来慢慢开始学从三个数中找出最大值 , 和对数组进行 ...

  4. c语言程序字体放大,C语言写的俄罗斯方块程序减小字体 增大字体 作者.docx

    C语言写的俄罗斯方块程序减小字体 增大字体 作者 C语言写的俄罗斯方块程序减小字体增大字体作者:佚名来源:不详发布时间:2009-9-21 1:11:22收藏到网摘:合作洽谈大概在最近两天之内编码完成 ...

  5. MIPS汇编实现冒泡排序法

    要求: 利用MIPS汇编实现冒泡排序法 初始化数据为:8,6,3,7,1,0,9,4,5,2 代码实现与解释: 数据: 主函数 排序函数: SWAP函数(交换数组当中两个元素) 输出函数: 运行程序: ...

  6. python语言翻译成汇编语言_计原 || 1计算机语言发展与计算机层次结构

    本文主要内容:计算机语言发展与计算机层次结构 约1500字 早期的计算机,只有机器语言 机器语言,就是直接用0.1代码表示的语言,用户必须用0和1来编写程序,用二进制的代码来表示一切需求 这对程序员的 ...

  7. c语言数独出题程序,我用C语言写解数独程序(一)

    我要用C语言写一个解数独题目的程序,从我刚开始接触数独的时候,我就这样告诉自己.记得那是暑假的一天.在家闲来无事,就翻开了以前买的一本 <数独>.从看前面的例题开始,然后自己解第一个题,之 ...

  8. javaBean:java语言写成的可重用的组件。

    所谓javaBean,是指符合如下标准的java类: 类是公共的;(public class 类名) 有一个无参的公共的构造器;(public 类名()) 有属性,且有对应的get.set方法(封装性 ...

  9. 子程序调用编程序例子_汇编程序设计:LCD1602静态显示

    嗨,大家好,昨天刚写好一个汇编程序,之前有bug,不能正确显示,经过一天的调试修改终于改好了,和大家分享一下. 我今天给大家介绍的是LCD1602的显示,该程序是用汇编语言来写的.我们先来看一下实物效 ...

  10. C语言做着做着会变成木马程序,为啥我用c语言写成的exe文件会被360当做木马?...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #includemain() { char t[2]; printf("问答游戏开始\n1.99毫升0.5mol·L-1硫酸跟101毫升1mol ...

最新文章

  1. 网络流24题(1) P2756 飞行员配对方案问题
  2. Hadoop集群搭建(九:各服务的启动)
  3. linux 内核 编译详解
  4. Java 三位正整数的个十百位数字的立方和
  5. python nan_python [吐槽]关于nan类型时遇到的问题
  6. MFC GDI绘图基础
  7. 函数mkdir、mkdirat和emdir
  8. java访问同一个变量_java – 从另一个类访问变量
  9. python map什么意思_Python中map是什么意思
  10. jquery pager 访问 java_基于JQuery的Pager分页器实现代码
  11. Python学习之字典详解
  12. node.js读取JSON文件
  13. 文言文已经没啥用了?错!还能编程用!
  14. python实现模拟登录云课堂智慧职教并获取课程信息(1)
  15. 区块链开发完整指南。如何开发一款区块链项目?
  16. 踩坑录·CacheCloud无法启动
  17. rpc error: code = Unavailable desc = connection error: desc = “transport: Error while dialing readin
  18. linux设置spi时钟频率,Linux下S3C2416的SPI设置问题,CLK和MOSI都没有输出,求助
  19. iphoneX的safari浏览器操作栏隐藏时兼容底部Home键
  20. 分布式系统学习共性总结:

热门文章

  1. Telink RDS IDE编译问题
  2. 多个jdk配置环境变量
  3. Pr入门系列之十四:处理音频
  4. python井字格游戏_python实现简单井字棋游戏
  5. java持久化 seri_Java 的序列化 (Serialization) 教程
  6. qq互联登录授权php配置,网站接入QQ登录(QQ互联)php版的流程
  7. Java学生档案管理系统的设计与实现
  8. uniapp 点击动画_uni-app animation动画
  9. pandas中DataFrame如何检测重复值
  10. excel查找并高亮展示重复值