Bootstrap

HNU-2024计算机系统实验-VSPM1.0

写在前面:

2024年春季学期,除第一个实验外,HNU计算机系统依然采用卡内基梅隆大学编写的教材CSAPP(深入理解计算机系统)配套的实验,这四个实验都非常有趣并且与考试关系十分密切(从近几年的期末考试趋势来看,一般都会有两道高分值汇编答题),希望所有同学都自己认真地把这四个实验做一遍,相信一定会有所收获。

第一个实验VSPM1.0,即Very Simple Prototype Machine 非常简单原型机,需要在上学期课程《电路与电子学》的基础上理解简单的汇编代码的运行以及原理,例如:跳转指令jg是怎么完成跳转的?这个实验虽然是四个实验中难度最小的,但是有很大的学习价值,为后续汇编代码的学习打下基础。

一、实验项目一

1.1 项目名称

原型机vspm1.0

1.2 实验目的

1)了解冯诺伊曼体系结构;

2)理解指令集结构及其作用;

3)理解计算机的运行过程,就是指令的执行过程,并初步掌握调试方法。

1.3 实验资源

1)vspm原型机以及wsl2子系统(搭载ubuntu20.04)

2)课程指导《最小系统与原型机》

课程组的老师推荐使用Virtual Box以及VMWare安装ubuntu虚拟机,有兴趣的同学可以尝试使用WSL2(Windows Subsystem Linux),我本人一个学期的使用体验是比VB/VM都要好,首先是安装非常方便,不需要繁杂的准备工序,不用考虑为虚拟机分配内存,同时它的打开方式也非常优雅,无需长时间的等待开机,点一下就行,并且WSL可以直接访问Windows里面的文件,最重要的一点是:由于本实验是使用java语言编写的,VB/VM上安装jdk21以上的java相当困难,WSL则要简单不少,唯一的缺点就是WSL只有一个终端,没有图形化界面(桌面这些),不过这门课程以及操作系统课程只使用终端就能顺利完成所有实验。

这里附上WSL2的安装教程:WSL2安装(详细过程)-CSDN博客

注:Linux与Windows中的路径格式不同,当在WSL中访问Windows的文件时除了复制地址外还需要做一些更改,以下是一个地址转换的例子:

Windows:C:\user\app

Linux:/mnt/c/user/app

由于缺少图形化界面,WSL无法使用老师上课演示的gedit命令,可以使用vim指令代替

例:

vim hello.c 表明打开hello.c文件,不过刚打开处于只读模式,需要按下字母键i进入插入模式(insert),输入结束之后按下esc键退出插入模式,接着输入:wq(看上去确实很奇怪),敲下回车就可以退出vim编辑器了。

二、实验任务

2.1 实验任务A

任务名称:完成文件a-inst.txt中代码的执行和相关操作

1.运行原型机,使用help指令查看原型机中的命令:

2.输入命令x 6 0000,查看内存地址0000开始的连续6个内存地址值:

3.输入si,执行第一条指令,即输入a到R1,输入4,并使用命令i r来查看寄存器的值:

4.可以看到,我们输入的数4已经存放进入R1中,接着执行接下来的操作,直至即将第一次跳转:

5.通过i r命令,观察发现寄存器R1的值此时仍然大于1,故即将跳转进入第二行,此处同时注意一处细节:jg的上条指令使用add来完成对R3的减三跳转操作而没有使用sub,因为要避免sub对jg跳转命令的影响:

6.继续使用si命令,直至jg不再执行跳转命令,循环结束:

7.此时R1=R1-1=0,说明在进行sub时,R1已经不再大于1,所以jg指令不再跳转,循环结束:

8.输出了所需要的值10=4+3+2+1,并正常停机,输入q命令退出vspm:

2.2 实验任务B

任务名称:运行并调试文件b-inst.txt、c-inst.txt中的代码,并对这些代码的工作进行解释:

对于b-inst.txt的调试运行:

代码工作解释:输入两个数a、b,比较他们的大小并输出较小的数。

对于c-inst.txt的调试运行:

代码工作解释:输入两个乘数a、b,输出他们的乘积。

三、思考问题

(1) 如何基于这些指令实现两个整数的乘法与除法?

乘法:根据代码文件c-inst.txt中的汇编代码可知,实现两个数的乘法可以通过循环运算加法来实现,例如执行a*b,可以将R1寄存器的值设置为b,将a的值存放到地址00000000中,再用R2来记录累加后的值,每一轮循环开始后,从内存地址00000010中取出上一轮完成累加的值放入寄存器R2,让R2加上a,再放回内存地址00000010中保存,同时使b的值减一,如此反复进行,直至b不再大于1,即完成了b个a累加的操作,最后输出R2即为a*b的值;

除法:实现两个数的除法也类似,即用循环运算减法来实现两数除法,例如执行a/b,可以将R1寄存器的值设置为b,将a的值存放到地址00000000中,再用R2来记录累减后的值,每一轮循环开始后,从内存地址00000000中取出上一轮完成累减的值放入寄存器R2,让R2减去b,再放回内存地址00000000中保存,同时使内存地址00000010的值加一,如此反复进行,直至a不再大于b,最后再根据余数判断是否需要加b,即完成了a/b的操作,最后输出内存地址00000010中的值即为a/b的值;内存地址中00000000即为a/b的余数。

这里附上我自己编写的d-inst除法代码,输入a、b两个数,输出a、b的商和余数:(PS:老师的实验指导书是没有要求手写除法代码的,但是写了的同学可以更容易在实验验收过程获得A以上的评分,建议大家有能力的都去自己写一个除法代码😉,理解了的话并不难,和乘法代码很相似)

6
in R1		#输入第一个数a
movb R0,R1	#将a的值存放入地址0000 0000
in R1		#输入第二个数b
movi 1
movb R0,R1	#将第二个数b存放入地址0000 0001
movi 1	#循环开始
movc R1,R0	#从内存中取出b的值,放入R1
movi 0
movc R2,R0	#从内存中取出a的值,放入R2
sub R2,R1		#a-b,并设置g值
movi 0
movb R0,R2
movi 2	#内存地址0000 0010中存放a/b的值
movc R1,R0	#将上一轮循环计算的a/b的值取出,放入R1
movi 1
add R1,R0		#每轮循环让a/b的值加一
movi 2
movb R0,R1	#将a/b的值存回内存空间0000 0010 
movd
movi -13
add R3,R0
jg
movi 0
movc R2,R0	#取出a/b的余数,此处由于循环的原因可能会多进行一次运算,需要加上一个b
movi 2	
movc R1,R0	#取出a/b的值,此处由于循环的原因可能会多进行一次运算,需要减1
movi -1
sub R2,R0
movd
movi 9
add R3,R0
jg
movi -1
add R1,R0
movi 1
movc R3,R0
add R2,R3
movi -1
add R2,R0
out R1
out R2
halt

(2) vspm1.0的指令集是否完备?如果是,那么如何证明(提示:搜索并阅读“可计算性理论”)?如果不是,那么要增加哪些指令?

一个语言被称为图灵完备语言,需要满足以下几个要求或特征:

1.具有基本算数和逻辑运算功能,例如位运算、加减乘除、布尔运算、比较等。

2.可以实现条件判断和循环操作,例如 if-else 语句、while 循环等。

3.具备无限循环能力,以便模拟图灵机。

4.可以进行任意长度的计算和存储数据,以便模拟图灵机。

5.支持函数或过程调用和递归,以便模拟复杂计算。

实际上,如果某种语言可以执行以上指令,就可以称为是图灵完备的。对于原型机而言,缺少了位运算指令(左移右移,按位与或非,异或)指令以及布尔运算指令,同时不具有非条件跳转的指令,该原型机不是图灵完备的。

(3) 如果一台计算机只支持加法、减法操作,那么能否计算三角函数,对数函数?

可以实现,因为在有限精度内,可以利用泰勒展开,将三角函数、对数函数等特殊函数展开为仅包括加减乘除运算的多项式函数,取一定精度,再利用加减法和循环的组合来实现乘法和除法进一步实现一定精度下多项式函数的计算。

(4) 对于某个需要完成的功能,如果既可以通过硬件上增加电路来实现,也可以通过其他已有指令的组合来实现,那么如何判断哪一种比较合适?

CISC的英文全称为“Complex Instruction Set Computer”,即“复杂指令系统计算机”、RISC的英文全称为“Reduced Instruction Set Computer”,即“精简指令集计算机”,硬件上增加电路对应的是CISC复杂指令集,通过已有指令的组合对应的是RISC指令集。

从硬件角度来看CISC处理的是不等长指令集,它必须对不等长指令进行分割,因此在执行单一指令的时候需要进行较多的处理工作。而RISC执行的是等长精简指令集,CPU在执行指令的时候速度较快且性能稳定。因此在并行处理方面RISC明显优于CISC,RISC可同时执行多条指令,它可将一条指令分割成若干个进程或线程,交由多个处理器同时执行。由于RISC执行的是精简指令集,所以它的制造工艺简单且成本低廉。

从软件角度来看,CISC运行的则是我们所熟识的DOS、Windows操作系统。而且它拥有大量的应用程序。因为全世界有65%以上的软件厂商都理为基于CISC体系结构的PC及其兼容机服务的,象赫赫有名的Microsoft就是其中的一家。而RISC在此方面却显得有些势单力薄。虽然在RISC上也可运行DOS、 Windows,但是需要一个翻译过程,所以运行速度要慢许多。 

因此通用机更适合通过硬件上增加电路来实现,专用机更适合通过其他已有指令的组合来实现。

在本实验中,老师还提供了课程组编写的编译器miniCC,具体使用方法可以参考我们当时某个班的助教学长给出的实验指导:(学长人太好了🥹)2024Spring> HNU-计算机系统-实验1-原型机vspm1.0-(试玩+验收)-CSDN博客

四、实验总结 

3.1 实验出现的问题

1.在第一个任务中,由于Virtual Box中自带java的jdk版本过低导致无法运行vspm原型机,后通过使用wsl2来代替虚拟机并安装jdk21的java将问题顺利解决(因为在VB上实在装不上,所以临时换虚拟机跑路了);

2.在第二个任务中未遇到问题。

3.2 心得体会

1.通过这个实验,我更深刻地理解了冯诺依曼体系结构以及图灵完备的判断;

2.我理解了模型机的基本使用方法,并且能够根据自己的需求编写汇编指令并顺利运行;

3.我明白了计算机系统这门课程不仅需要在课堂上学习理论知识,更应该去动手实践,自己去跑实验、配置环境,遇到bug不应该慌张,相信认真分析总能找到解决方法的,在一次次的报错、改错过程中,我们也能不断提升自己的能力,为未来更深入的学习打下基础。

;