计算机组成原理mips汇编大作业报告(冒泡排序、选择排序)

  1. 请结合冯诺依曼思想,对本次实践所使用的模型机进行描述,并对比《单周期MIPS (硬布线)》中使用的模型机的相同和不同之处。
    问题一:结合冯诺依曼思想,对本次实践所用的模型机进行描述
    冯诺依曼思想:计算机处理的数据和指令一律用二进制数表示,顺序执行程序,计算机硬件由运算器、控制器、存储器、输入设备和输出设备五大部分构成。
    在本次实验所使用的模型机中,除了最开始输入存储器的指令为16进制之外,在该模型机内部接收或者传输的指令都为2进制。
    在该模型机中,需要把要执行的指令和处理的数据首先存入存储器中,程序执行时,将自动地并按顺序从存储器中取出指令一条一条地执行。
    本模型机的运算器为:
    运算器由算数逻辑单元ALU、状态寄存器、通用寄存器等组成
    算数逻辑单元ALU如图1-1,打开后如图1-2

    在这里插入图片描述
    状态寄存器如图1-3
    在这里插入图片描述

通用寄存器如图1-4
在这里插入图片描述
本模型机的控制器如图1-5,打开后如图1-6,分析如下:1.控制器的输入信号为:指令字,Func字段,时钟信号,复位信号2.控制器的输出信号为:多路选择器选择信号,内存访问控制信号,寄存器写使能信号,运算器控制信号,指令译码信号
在这里插入图片描述
在这里插入图片描述
本模型机的存储器如图1-7
在这里插入图片描述
问题二:两模型机的相同之处与不同之处
相同之处:两模型机都符合冯诺依曼思想:对于单周期来说也包含存储器,运算器,控制器。且整个数据和指令在内部也以二进制的方式传输。符合顺序执行,需要把要执行的指令和处理的数据首先存入存储器中,程序执行时,将自动地并按顺序从存储器中取出指令一条一条地执行。
不同之处:

  1. 定义不同:单时钟周期硬布线是一个时钟周期执行一条指令,多时钟周期硬布线是一条指令多个时钟周期。
    2.在单周期中含有数据存储器和指令存储器,指令和数据分开存放。但在多周期硬布线中存储器未分开使用,由IorD来控制是数据还是指令。IorD为0,则选择上面的指令,IorD为1则选择下面的数据。如图2-1
    在这里插入图片描述
    3.在单周期硬布线中没有PCWrite,即不能对PC进行写操作,但在多周期硬布线中含有PCwrite,在多周期硬布线中要进行跳转去更改PC的值,一条指令占用不止一个时钟周期,有多个时钟周期,要执行PC+4->PC操作。如图2-2、2-3
    在这里插入图片描述
    在这里插入图片描述
    4.在单周期硬布线中只含有一个AluSrcB,但在多周期硬布线中同时含有AluSrcB和AluSrcA。如图2-4
    在这里插入图片描述
    5.单周期硬布线无微程序控制器,为组合逻辑控制器,而多周期硬布线具有多周期微程序控制器,打开控制存储器如图2-5:
    在这里插入图片描述
    以013201和030010为例分析:
    013201H=0000 0001 0011 0010 0000 0001
    第3~0位:0001表示下一微地址指令地址为1
    第4位:0,判断逻辑,将下址字段送入Uar。如图2-6
    在这里插入图片描述
    第6~5位: 00 ALU_Control为00,则ALU_OP=5。如图2-7
    在这里插入图片描述
    第14~7位:011 0010 0,则MemRead=1,PcWrite=1,IRWrite=1。如图2-8
    在这里插入图片描述
    第16~15位:01,ALUSrcB=01,则将00000004传入ALUB端,即进行PC+4,如图2-9、2-10
    在这里插入图片描述
    在这里插入图片描述
    第19~17:000

030010H=0000 0011 0000 0000 0010 0000
第3~0位:0000表示下一微地址指令地址为0,但是第四位为1,所以没有选中
第4位:1,判断逻辑,将微程序入口送入Uar。如图2-11
在这里插入图片描述
第6~5位:00 ALU_Control=00,则ALU_OP=5。如图2-12
在这里插入图片描述
第14~7:都为0
第16~15:10,ALUSrcB=10,则将扩展过的32位立即数传入B端。如图2-13
在这里插入图片描述
第19~17:001,ALUSrcA=1,则将R1的值传入A端。如图2-14
在这里插入图片描述
2. 结合自己所学知识,请对所给的冒泡法排序程序进行分析。
冒泡排序的原理是:从左到右,相邻元素进行比较。每次比较一轮,就会找到序列中最大的一个或最小的一个。这个数就会从序列的最右边冒出来。
以从小到大排序为例,第一轮比较后,所有数中最大的那个数就会浮到最右边;第二轮比较后,所有数中第二大的那个数就会浮到倒数第二个位置……就这样一轮一轮地比较,最后实现从小到大排序。
有n个数据,则需比较n-1轮。
冒泡排序的伪代码如图3-1:
在这里插入图片描述
C代码如图3-2:

在这里插入图片描述
此段代码分析如下:

.text
#################################################################################
#本程序实现0x80开始的8个字单元的降序排序,此程序可在mars mips仿真器中运行,字地址0x80
#运行时请将Mars Setting中的Memory Configuration设置为Compact,data at address 0
#
#################################################################################
 .text
sort_init:
 addi $s0,$0,-1          给$s0赋值为-1,将-1+$0的值传到$s0号寄存器中 
 addi $s1,$0,0           $S1就是相当于C语言的int i,即给i赋初值为0
 sw $s0,128($s1)         写入到实际地址$s1 0x80单元   128*4/4=128=0x80
 addi $s0,$s0,1          给$s0赋值为0,将1+$s0=1+(-1)=0的值传到$s0号寄存器中
 addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+4)/4=129=0x81单元  
 addi $s0,$s0,1          给$s0赋值为1,将1+$s0=1+0=1的值传到$s0号寄存器中
 addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+8)/4=130=0x82单元
 addi $s0,$s0,1          给$s0赋值为2,将1+$s0=1+1=2的值传到$s0号寄存器中
 addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+12)/4=131=0x83单元
 addi $s0,$s0,1          给$s0赋值为3,将1+$s0=1+2=3的值传到$s0号寄存器中
 addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+16)/4=132=0x84单元
 addi $s0,$s0,1          给$s0赋值为4,将1+$s0=1+3=4的值传到$s0号寄存器中
addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+20)/4=133=0x85单元
 addi $s0,$s0,1          给$s0赋值为5,将1+$s0=1+4=5的值传到$s0号寄存器中
 addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+24)/4=134=0x86单元
 addi $s0,$s0,1          给$s0赋值为6,将1+$s0=1+5=6的值传到$s0号寄存器中
 addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+28)/4=135=0x87单元
 
 add $s0,$zero,$zero      $s0=0,即int i=0
 addi $s1,$zero,28   #排序区间  $s1=28,int j=7;
sort_loop:
 lw $s3,128($s0)0x80里的值赋给$s3,即temp1=A[i],后面循环后为0x81\0x82...          
 lw $s4,128($s1)0x87里的值赋给$s4,即temp2=A[j],后面循环时即为0x86\0x85...
 slt $t0,$s3,$s4          若$s3<$s4,则$t0=1,反之为0
 beq $t0,$0,sort_next   #降序排序     为真则跳过直接执行下一循环,为假则交换
 sw $s3, 128($s1)         把s3寄存器的值传给0x87单元,即A[j]=temp1 后面循环时依次递减
 sw $s4, 128($s0)         把s4寄存器的值传给0x80,即A[i]=temp2,后面循环时为0x81\0x82...
sort_next:
 addi $s1, $s1, -4        将$s1-4的值存入s1寄存器中,即j=j-1/2/3/.....
 bne $s0, $s1, sort_loop  继续内层循环
 
 
 addi $s0,$s0,4           将$s0+4的值存入$0号寄存器,即i=i+1
 addi $s1,$zero,2828传入$s1中,即恢复int j=7,表示由于i引起变化新一轮内循环重新开始
 bne $s0, $s1, sort_loop  $s0不等于$s1时。跳转到上面执行循环,相等时表示排序已结束,退出
 addi   $v0,$zero,10         # system call for exit
 syscall                  # we are out of here.   

代码运行结果分析示意图如图3-3:
在这里插入图片描述
3. 请用另一种排序法将“2”中数据按照由大到小排序。若需要添加指令,请对控制器做修改。
此题选用选择排序的方法:
选择排序:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。
选择排序伪代码如图4-1:
在这里插入图片描述
C语言代码如图4-2:
在这里插入图片描述
汇编代码如下:

.text
sort_init:
 addi $s0,$0,-1          给$s0赋值为-1,将-1+$0的值传到$s0号寄存器中 
 addi $s1,$0,0           $S1就是相当于C语言的int i,即给i赋初值为0
 sw $s0,128($s1)         写入到实际地址$s1 0x80单元   128*4/4=128=0x80
 addi $s0,$s0,1          给$s0赋值为0,将1+$s0=1+(-1)=0的值传到$s0号寄存器中
 addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+4)/4=129=0x81单元  
 addi $s0,$s0,1          给$s0赋值为1,将1+$s0=1+0=1的值传到$s0号寄存器中
 addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+8)/4=130=0x82单元
 addi $s0,$s0,1          给$s0赋值为2,将1+$s0=1+1=2的值传到$s0号寄存器中
 addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+12)/4=131=0x83单元
 addi $s0,$s0,1          给$s0赋值为3,将1+$s0=1+2=3的值传到$s0号寄存器中
 addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+16)/4=132=0x84单元
 addi $s0,$s0,1          给$s0赋值为4,将1+$s0=1+3=4的值传到$s0号寄存器中
 addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+20)/4=133=0x85单元
 addi $s0,$s0,1          给$s0赋值为5,将1+$s0=1+4=5的值传到$s0号寄存器中
 addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+24)/4=134=0x86单元
 addi $s0,$s0,1          给$s0赋值为6,将1+$s0=1+5=6的值传到$s0号寄存器中
 addi $s1,$s1,4          将$s1+4的值传入到$s1号寄存器中,即c代码中的i=i+1
 sw $s0,128($s1)         写入实际地址 (128*4+28)/4=135=0x87单元
 
 add $s0,$zero,$zero        $s0=0,即int i=0
 addi $s1,$zero,32   #排序区间  $s1=32,即n=8;
 addi $s2,$s0,4             $s2=$s0+4,即 int j=i+1
 add $t1,$s0,$0             $t1=$s0+$0,即int m=i
sort_loop:
 lw $s3,128($s2)            从存储器中取出数存到寄存器$s3中
 lw $s4,128($t1)            从存储器中取出数存到寄存器$s4中
 slt $t0,$s3,$s4            若$s3<$s4,则$t0=1,反之为0
 bne $t0,$0,sort_next   #降序排序     相等则继续执行,不等则跳过交换步骤直接进入下一循环
 sw $s3, 128($t1)           将寄存器$3的数存到对应的地址单元即存储器内
 sw $s4, 128($s2)           将寄存器$4的数存到对应的地址单元即存储器内
sort_next:
 addi $s2, $s2, 4           将$s2+4的值存入s2寄存器中,即j=j+1/2/3/.....
 bne $s2, $s1, sort_loop  继续内层循环
 addi $s0,$s0,4             将$s0+4的值存入$s0号寄存器,即i=i+1
 addi $s2,$s0,4             将$s0+4的值存入$s2,即i=j+1
 add $t1,$s0,$0             将$s0+$0的值存入$t1,表示下一次外循环导致m的值重新等于i
 addi $s1,$zero,3232传入$s1中,即恢复int n=8,
 add $s6,$s1,-4             表示外循环i<n-1,此条指令算出n-1
 bne $s0, $s6, sort_loop     $s0不等于$s6时。跳转到上面执行循环,相等时表示排序已结束,退出
 addi   $v0,$zero,10         # system call for exit
 syscall                  # we are out of here.  

汇编代码对应的16进制指令如下:

2010ffff 20110000 ae300200 22100001 22310004 ae300200 22100001 22310004
ae300200 22100001 22310004 ae300200 22100001 22310004 ae300200 22100001
22310004 ae300200 22100001 22310004 ae300200 22100001 22310004 ae300200
8020 20110020 22120004 02004820 8e530200 8d340200 274402a 15000002 ad330200 ae540200 22520004 1651fff8 22100004 22120004 02004820 20110020 2236fffc 1616fff2 2002000a c

程序的运行结果如图
在这里插入图片描述
在这里插入图片描述
以上为此次实验全部内容,欢迎讨论!

  • 10
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 计算机组成原理MIPS大作业是关于使用Verilog语言实现MIPS指令集的设计与开发。MIPS(Microprocessor without Interlocked Pipeline Stages)是一种精简指令集(RISC)架构,广泛应用于嵌入式系统和大规模计算中。 在这个大作业中,我们需要使用Verilog语言来实现MIPS处理器的核心功能,包括指令译码、数据通路、控制单元等。首先,我们需要根据MIPS指令集的格式和规则,设计和编写Verilog模块来进行指令译码,将二进制指令解析为对应的操作码和操作数。同时,我们还需要设计和实现数据通路,包括寄存器堆、ALU(算术逻辑单元)、数据存储器等,用于执行指令中的操作并存储数据。最后,我们还需要设计和编写控制单元,通过产生控制信号来驱动数据通路的操作。 在实现过程中,我们需要注意保持指令的顺序和正确性,确保每一条指令的执行都符合MIPS指令集的规则。我们还需要进行仿真和测试,使用Verilog的仿真工具来模拟和验证实现的正确性。 此外,为了进一步提升处理器的性能,我们可以添加流水线和多级缓存等技术来提高指令的执行效率。流水线可以将指令的执行划分为多个阶段,使得每个阶段可以并行执行,从而提高处理器的吞吐量。而多级缓存可以通过提前缓存数据,减少对主存的访问时间,进一步加快指令的执行速度。 总之,计算机组成原理MIPS大作业是一个重要且具有挑战性的项目,需要我们熟练掌握Verilog语言和MIPS指令集,通过设计与实现MIPS处理器的核心结构和功能,来加深对计算机组成原理的理解和实践。 ### 回答2: 计算机组成原理MIPS大作业Verilog是一门以硬件描述语言Verilog实现MIPS指令集的课程项目。MIPS指令集是一种经典的RISC指令集架构,由于其简洁、清晰的设计,常被用于CPU、嵌入式系统等领域。 该大作业的主要目标是使用Verilog HDL编写一个能够正确执行MIPS指令集的CPU模拟器。实现一个完整的CPU模拟器是一个复杂而庞大的工程,需要包含一系列功能模块,如指令存储器、数据存储器、寄存器组、ALU等。 在实现过程中,首先需要了解MIPS指令集的特点和功能,包括指令的格式、指令的执行过程及指令的功能。然后按照MIPS指令集的要求,设计并编写各种功能模块的Verilog代码。同时,还需要设计合适的时钟控制电路和数据通路,以确保指令能够按顺序、正确地执行。最后,进行功能验证和测试,验证所写的模块能够正确地执行各种MIPS指令。 在实现过程中,还需要注意一些细节,如处理异常和中断、支持乘法和除法指令、实现流水线等。这些都是实际的CPU设计中常见的问题。 通过完成这个大作业,可以深入理解计算机组成原理中的各个概念和原理,并通过实践掌握Verilog HDL编程技能。此外,通过调试和测试,还可以提高自己的问题解决能力和团队协作能力。 总而言之,计算机组成原理MIPS大作业Verilog是一个能够锻炼自己对计算硬件设计、MIPS指令集和Verilog HDL编程的综合能力的项目。完成该大作业可以提高我们对计算原理的理解,并为后续的学习和研究打下坚实的基础。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值