HNU计算机系统实验一 原型机

写在前面

hnu的计算机系统这门课程教的还是挺好的,几个实验也很好玩,认真做也能学到很多东西。从这篇开始记录22级这门课的四个实验,仅供学习交流使用哦。

实验一用的是学校老师自己设计的一个原型机,而后面的三个实验都是书本配套的实验(和卡内基梅隆大学的学生做的一样,只不过他们还有很多其他实验,而教学组只挑选了其中三个布置)。

1 实验任务

1.1 实验任务A

任务名称:原型机练习

1.1.1 按照实验指导书中的实验步骤,完成对a-inst.txt的相关操作;

①进入终端,使用./vspm a-inst.txt来运行原型机1.0的模拟器,其中a-inst.txt为代码文件。

a-inst.txt中的代码如下图所示。分析代码可知,此代码的功能是实现从输入的数一直加到1并得到结果。

运行后界面如下图所示。

②在运行后,提示将要执行的指令地址及内容。此时输入si则表示执行此指令,同时也可以输入其他的指令,使用help可以查看此模拟器支持的命令。

输入help后界面如下图所示。

③此时输入i r,可以查看各个寄存器的值,而输入x 6 0000则表示查看从0000开始的连续6个内存地址值。结果如下图所示。

④输入si,则表示运行一条指令。例如此时运行的指令是“in R1”,表示等待输入,输入一个值5,在输入完成后运行i r指令,就可以看到输入的值5已经存放在R1寄存器中。每个寄存器的值都用十进制和十六进制表示,如下图所示。

⑤接下来执行指令“movi 1”,意思是设置R0为1。执行完毕以后,运行i r指令可以看到R0的值已经变为1。如下图所示。

⑥接下来执行指令“add R2,R1”。执行完毕以后,运行i r指令可以看到R1+R2的结果5已经存放到R2中。如下图所示。

⑦接下来执行指令“sub R1,R0”。执行完毕以后,运行i r指令可以看到R1-R0的结果4已经存放到R2中,同时由于R1-R0>0,G的值设置为1。如下图所示。

⑧接下来执行指令“movd”。执行完毕以后,运行i r指令可以看到当前PC的值10已经存放到R3中。同时再执行指令“movi -3”,使得存放-3到R0中。如下图所示。

⑨接下来执行指令“add R3,R0”。将R3的值减去3,为后面跳转到地址为0x07的“movi 1”指令做准备。注意不能用SUB指令,否则会影响G值。如下图所示。

⑩执行指令“jg”。由于此时G值为1即上面进行减法时R1-1还大于0,因此会进行跳转,将跳转到地址为0x07的“movi 1”指令。执行结果如下。

继续执行接下来的指令。可以看到,第二轮循环时,R2中的结果为5+4=9,执行sub指令后G值仍为1。如下图所示。

输入c执行指令直到程序结束,我们可以得到最终的结果5+4+3+2+1=15

1.1.2 运行并调试b-inst.txt,并对代码所做的工作进行解释;

①运行调试

b-inst.txt中的代码如下图所示。

开始运行。

样例1a=5,b=2;

输入第一个数a为5,第二个数b为2,并将a的值保存在R0中。用si执行指令完成后,运行指令i r查看寄存器的值,结果如下图所示。

接下来执行指令“sub R1,R2”。执行完毕以后,运行i r指令可以看到R1-R2的结果3已经存放到R1中,同时由于R1-R0>0,G的值设置为1。如下图所示。

然后继续执行指令,将a的值5保存到R1,将PC值赋给R3,将R0值设置为6。如下图所示。

继续执行,将R3的值加6,使得后续如果能跳转的话就跳转到地址为00010001(17)的指令“out R0”处。b的值2保存到R0.如下图所示。

因为G为1,所以可以进行跳转,跳转到地址为0001 0001(17)的指令“out R0”处,直接输出R0的值也就是b(2)。

样例2a=5,b=8;

先用“si 9”执行9条指令直到跳转指令jg之前。因为a是5,b是8,因此a-b<0,G的值会被设置为0。在执行jg指令后,并不会跳转,而是顺序执行接下来的指令。先把a的值保存到R0,再输出R0,最后输出的也就是a的值5。运行结果如下。

②工作解释

b-inst.txt中的每一行代码的解释已附在右侧。通过分析代码和上述两个样例的实操过程可知,此代码的功能是将输入的两个整数进行大小比较,并输出其中较小的那个数,即min(a,b)功能。

1.1.3 运行并调试c-inst.txt,并对代码所做的工作进行解释;

①运行调试

c-inst.txt中的代码如下图所示。

样例:a=4,b=5;

一开始为准备阶段,先将乘数a和b的值分别存到内存0000 0000和0000 0001处,同时,结果的值在内存0000 0010处。如下图所示。

a*b即将b个a相加,将b作为计数,一直将结果加上数a,直到b为0为止。继续执行代码,第一次循环后,寄存器中的值及内存中的值如图所示。

继续执行指令,将当前PC的值保存到R3,再通过“movi -12”和“add R3 R0”指令使得R3的值为25-12=13即0000 1011。因为此时G为1,后续jg指令执行后,跳转到地址0000 1011的指令“movi 1”继续执行(因为b仍然大于0,因此继续进行循环加法)。如下图所示。

继续上述代码的循环,第二次循环后,内存中的值如下图所示。

第三次循环:

第四次循环:

第五次循环后,由于此时在执行上面的sub减法之后,b已经等于0了,因此此时G的值为0,jg指令不会进行跳转,循环结束,顺序执行接下来的指令。如下图所示。

接下来将内存地址0000 0010处的结果取出来存到R1中并打印输出,得到整数乘法运算4*5的结果20。如图所示。

②工作解释

c-inst.txt中的每一行代码的解释已附在右侧。通过分析代码和上述样例的实操过程可知,此代码的功能是实现将输入的整数进行乘法运算并输出结果。虽然原型机中并没有直接的乘法指令,但是可以通过条件判断和加法循环的方式实现乘法。

1.2 实验任务B

任务名称:思考问题

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

①乘法

两个整数a和b的乘法a*b即将b个a相加,将b作为计数,一直将结果加上数a,直到b为0为止。

具体代码如下所示。

在内存地址0x00处保存数a,0x01处保存数b,如下左图所示。

同时,将结果值存在内存地址0x02处,其初始值为0。每次循环结束后,内存0x01中b的值自减1,内存0x02中结果值加上a。当循环结束时,内存0x01中的值为0,内存0x02中的结果为b*a即乘法所得结果。如下右图所示。

注意,由于原型机的硬件配置是4个8位寄存器与256字节的内存,且存储的数字是采用补码表示的,因此硬件上是无法完成任意正整数的乘法计算的。

由于寄存器和内存仅有8位,无法直接表示超过127的数,因此一旦乘法所得结果超过了127,结果就会错误的显示为负数。例如,如果尝试计算 64×2=128,在8位二进制中,128是表示为10000000,这在8位有符号系统中被解释为-128而不是+128,因为最高位是1。

因此对于原型机而言,只能实现结果小于127的正整数乘法。

②除法

两个整数a和b的除法a÷b即累次做减法,每次减去除数b,记录做减法的次数即得到除法结果的整数部分。最后对不可整除情况,作取余数处理,得到余数部分。

即用两个8位输出结果

00000000

00000000

高位表示整数部分,低位为余数部分。

除法具体代码及内存中存储的值如下图所示。内存0x00处存储值b,0x01处存储整数部分的结果值ans。

同样的,由于原型机硬件限制即寄存器和内存仅有8位,可能会出现溢出问题,因此只能实现小于127的正整数的除法。

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

是图灵完备的。

直观判断方法是, 一门语言如果允许你写出死循环,那么它很大可能就是图灵完备的。而vspm指令集是允许我们写出死循环的。

在可计算性理论,如果一系列操作数据的规则(如指令集、编程语言、细胞自动机)可以用来模拟任何一种图灵机,那么它是图灵完备的。

证明的方法是,参考一种叫做brainfuck的语言,这是一种最简单的图灵完全的语言,而且已经被证明了。如果vspm指令集能够模拟实现brainfuck的所有功能,那么他一定是图灵完备的。

Brainfuck 语言只有八个简单的命令和一个指令指针,除此之外没有其他的构造。下面是 Brainfuck 语言的所有指令及其功能:

‘>’ :移动指针到下一个数组单元。

vspm中程序计数器PC和jmp跳转指令等的使用可以移动指针到下一个数组单元。

‘<’ :移动指针到上一个数组单元。

同样的,vspm中程序计数器PC和jmp跳转指令等的使用也可以移动指针到上一个数组单元。

‘+’ :增加指针指向的数组单元的值

vspm中将数组单元的值取到寄存器中,使用 ADD 指令增加其值,然后存回去即可。

‘-’ :减少指针指向的数组单元的值。

类似地,使用 SUB 指令来减少值。

‘.’ :输出指针指向的数组单元的字节。

vspm中将数组单元的值取到寄存器中,使用 OUT 指令将寄存器的值输出。

‘,’ :输入一个字符并保存在指针指向的数组单元。

vspm中使用 IN 指令将输入保存到寄存器中,再由寄存器放到当前数组单元。

‘[’ :如果指针当前位置的字节为零,则跳转到对应的‘]’之后的命令。(跳过循环体)

映射到vspm中,即使用 G值和 JG 指令来实现条件判断和循环的开始。如果G值为1,则发生跳转;如果G值为0,则不跳转。

‘]’ :如果指针当前位置的字节不为零,则跳转回对应的‘[’命令之后的位置。(回到循环开始的位置)

同样地,映射到vspm中,即使用 G值和 JG 指令来实现条件判断和循环的结束。如果G值为1,则发生跳转;如果G值为0,则不跳转。

因此,brainfuck的所有功能可以映射到vspm指令集的相应操作上,也即vspm指令集能够模拟实现brainfuck的所有功能,因此vspm1.0的指令集是图灵完备的。

1.2.3 如果一台计算机只支持加法、减法操作,那么能否计算三角函数,对数函数?(提示:搜索并阅读“泰勒级数展开”等内容)。

能计算三角函数和对数函数。

这是通过使用泰勒级数展开来实现的。泰勒级数是一个无限和,可以用来表示许多不同的函数,特别是在某一点附近的函数值。

对于任何可以通过泰勒级数展开的函数,我们可以将该函数表示为一个多项式的和,这个多项式的系数是由函数的导数在某一点的值确定的。例如:

对于三角函数如正弦函数sin(x),其泰勒级数展开式(在x=0处)是:

对于自然对数函数ln(1+x),其泰勒级数展开式(在x=0处)是:

要使用加法和减法来计算这些函数的近似值,可以选择一个足够高的项数N来近似泰勒级数,并使用加法和减法来计算每一项的值及它们的总和。虽然计算每个项可能需要乘法和除法,但由思考题1可知乘法和除法可以用加法和减法来实现。

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

CPU从指令集的特点上可以分为两类:CISCRISC

RISC(精简指令集计算)

优点:RISC架构旨在使用较少的指令种类进行高效计算,每个指令的执行时间都非常短暂且执行周期数相同。这意味着硬件设计可以更简单,更容易实现指令流水线化,从而提高性能。对于新功能,RISC倾向于通过软件在已有的简单指令集上实现。

适用情况:当系统需要高效率、低功耗,且对芯片成本和设计复杂度有较高要求时,RISC是更合适的选择。

CISC(复杂指令集计算)

优点:CISC架构通过在硬件中实现更复杂的指令来减少某些操作所需的指令数,理论上可以减少程序的大小,提高执行效率。对于新功能,CISC可能通过增加新的复杂指令直接在硬件上实现。

适用情况:当系统需要执行大量复杂操作,且对程序的空间效率有较高要求时,CISC可能是更好的选择。

因此,通过硬件上增加电路来实现也即使用CISC架构,通过其他已有指令的组合来实现也即使用RISC架构。

判断哪一种比较合适可以从以下几个方面考虑。

性能需求:考虑目标应用对性能的需求。如果性能是关键考虑因素,评估通过硬件增加新电路与通过软件实现相比,哪种方式更能满足性能需求。

功耗与成本:硬件增加复杂电路可能会增加功耗和成本。如果需要低功耗或成本敏感,通过现有指令组合实现功能即使用RISC架构可能更合适。

开发与维护复杂度:硬件修改通常比软件修改成本高,且不易改动。如果预期未来会频繁修改或更新功能,软件实现即使用RISC架构可提供更高的灵活性。

兼容性与可移植性:软件实现的功能更容易在不同的硬件平台上移植和适应。如果目标是支持多平台或保持良好的兼容性,软件实现即使用RISC架构可能更有优势。

总结来说,选择硬件实现(CISC)还是软件实现(RISC)需要根据具体应用的性能需求、成本限制、开发与维护的复杂度以及兼容性与可移植性等因素综合考虑。

2 总结(实验中出现的问题)

在实验任务A中,出现的问题有:

1. 一开始无法运行vspm程序,终端出现错误信息。上网查询以后发现是因为java版本过低的原因。更新java并配置好环境变量以后,成功运行了vspm

2. 一开始对vspm的使用不是特别熟练,经过查看help,以及多次对a-inst.txtb-inst.txtc-inst.txt的运行调试以后,已经熟练掌握了vspm的使用方法,并且深入理解了各条指令的含义。

在实验任务B中,出现的问题有:

1. 一开始自己在文档里写的乘法和除法汇编代码无法在vspm里运行,猜测可能是格式不对的问题。后来通过使用miniCC编译链接等操作先生成文档,再在此文档中编写自己的汇编代码,最后成功运行。

2. 对于后面几个思考题的相关知识不太了解,特别是第二道思考题的完备性不知道如何证明。通过仔细研究提示的搜索内容以及上网查找更多相关知识,最终成功解决了问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值