- 请问:一个不具备“算法”特性的过程,能否采用结构化编程的三个基本结构来构建程序?如果可以,请给出一个例子(提示:有关“算法”的定义,参考第1章)。
可以。比如,某个程序进入死循环,这个就不符合算法的“有限性”。 - LC-3没有提供减法指令。如果要对两个数做减法操作,你必须写一个函数来完成它。给出两个整数减法操作的系统分解过程。
开始
输入两个整数R0,R1
对R1取反
将R1加一
将R0,R1相加
结束 - 回顾前几章的“machine busy”例子。假设地址x4000包含了一个整数(范围为0~15),指示刚变为“忙”(busy)状态的及其编号。再假设x4001的内容告诉我们哪些机器正处于忙(busy)状态,哪些机器正处于空闲(idle)状态。试写一个LC-3的机器语言程序,根据x4000的内容(刚处于busy的机器编号)设置x4001的对应位。
例如,假设该程序执行之初x4000的内容为x0005,x4001的内容为x3101,则程序执行之后,x4001的内容应该变为x3121(提示:LC-3没有提供OR操作,你需要使用AND和NOT的组合操作实现OR操作)。
开始
读取x4000整数到R0:LD,R0,x4000
初始化R1:AND,R1,#0
将R0和R1相加,结果赋值给R1:ADD,R1,R0,R1
将R0减一:ADD,R0,#-1
BRz 跳转第3步:BRz 第3行
读取x4001内容到R2:LD,R2,x4001
将R1取反:NOT,R1
将R2取反:NOT,R2
将R1,R2相加赋值给R3:ADD,R3,R1,R2
将R3取反:NOT R3
结束 - 试写一个LC-3程序,比较R1和R2的内容并设置R0。如果R1=R2,则R0=0;如果R1>R2,则R0=1;如果R1<R2,则R0=-1。
开始
读取R1
读取R2
初始化R0
将R2取反
将R2加1
将R1和R2相加,赋值给R0
BRz 跳转到结束
BRn
BRp
5. 下面的两个乘法算法哪一个更好,为什么?88x3=88+88+88或3+3+3+3…+3。
第一种比较好,因为程序步骤更小,意味着消耗资源更小。
6. 基于习题6.3和6.4的答案,写一个高效率的两个整数的乘法程序,并将结果保存在R3。给出该问题的系统分解过程,从问题描述到最后的程序(提示:所谓的“高效率”,参考习题6.5的讨论)。
7. 阅读以下LC-3代码,请问该程序的任务是什么?
将x300E开始和x3013开始的两个列表,相加结果保存在x300E中,两个列表各5个数。
9. 6.1.4节的字符数统计程序中,为什么一定要初始化R2?换句话说,如果我们将R2←0的这行代码删除,该程序可能会出什么问题?
11. 采用循环结构,写一个LC-3程序,在屏幕上显示100个Z字符。
12. 采用条件结构,写一个LC-3程序,判断存放在R2中的数值是否是“奇数”(odd)。
13. 写一个LC-3程序,将地址A到地址B之间的所有内存单元的内容加1。假设这些内存单元的内容已被初始化为有意义的数值,而地址A和B的具体地址分别从x3100和x3101内存单元获得(提示:数据的访问为间接寻址方式)。
14. a. 写一个echo程序,即将键盘输入的字符回显在屏幕上。假如刚才的键盘输入为字符R,则程序马上将字符R输出在屏幕上。
b. 将a的问题扩展一下,每次回显一行(而不是一个字符)。例如,用户输入“The quick brown fox jumps over the lazy dog.”,则程序一直等待(无显示输出),直到用户输入回车键(Enter键,ASCII码为x0A),才将进行一次性输出。
15. 已知通过数值的自身相加操作可以实现该数的左移1位操作。例如,二进制数0011自己加自己,结果为0110(即等价于左移1位)。但是右移1位的操作却不是简单的事情。设计一个LC-3程序,将x3100的内容右移1位。
16. 阅读下面的机器语言程序:
问:R1的初始值为多少的时候,才能使R2的最终值为3?
17. 下表显示的是x3010程序执行之前(before)和执行之后(after)的内存和寄存器内容变化。你的任务是:判断存放在x3010的指令是什么指令(注意,以下的信息足以判断出该指令是什么,所以“细心+耐心”)?
18. 地址x3000~x3006之间存放了一段LC-3程序。程序从x3000开始执行。我们在执行过程中跟踪记录MAR的所有变化值,获得以下序列值,我们称这个序列值为“跟踪记录”。
下表显示的内存x3000~x3006的内容。你的任务是填充表中空格(0或1),结合上面的MAR跟踪记录信息。
20. 下表显示的是位于x3210的LC-3指令在执行之前和执行之后的内存和寄存器内容变化。你的任务是:判断存放在x3210的指令是什么指令(注意,以下的信息足以判断出该指令是什么,所以“细心+耐心”)。
22. LC-3没有提供除法指令。程序员必须写一个函数才能实现除法操作。给出求解两个“正整数”除法问题的系统分解。要求:LC-3程序从x3000开始执行,被除数位于x4000,除数位于x4001,商存放在x5000,余数存放在x5001。
23. 有时我们希望将一个消息(message)加密(如不希望好奇者偷看)。消息是由一串ASCII字符组成的,每个ASCII字符占据一个内存单元(且bit[15:8]都为0);存放是连续的(即相邻的消息字符之间不会有间隔,也不会倒序),且该字符串的结束必定是x000。
一个没有上过这门课的学生写下这样一个程序:从x4000开始,将每个字符都加4,然后存放在x5000开始的内存中。例如,假设x4000开始的内容是“Matt”,则加密后存放在x5000的内容应该是“Qeyy”。但是,他/她的代码中存在4个bug。找出它们并予以纠正。
24. 重做习题6.18,将范围扩展为“所有整数”,而不仅仅是“正整数”。
参考:https://github.com/QSCTech/zju-icicles/blob/master/计算机系统概论/作业答案/ch06_complete.pdf