计算系统概论实验Lab 6——C重写Lab1-5

news/2024/11/23 12:59:26/

Lab 6 C重写Lab1-5

Purpose

使用高级编程语言(例如C / C++)来实现以前编写的所有代码。请注意,该算法需要与之前使用的算法一致

condition:

  1. 明确禁止使用LC3不直接支持的*、/、%>><<等操作及等效库函数;
  2. 可以使用+,-,=,++,--,==,!=,<,>,<=,>=,&,|,~;
  3. 可以使用 for 、 while 、do while 、if 、continue 、break、switch case;
  4. 可以定义不违反上述规则的帮助功能。

several examples:

在这里插入图片描述

Procedure

lab1:counting how many 1

int16_t lab1(int16_t a, int16_t b) {// initializeint16_t res = 0, ptr = 1;// calculationwhile(b--){if(a&ptr)res++;ptr += ptr ;}// return valuereturn res;
}

第一个实验是统计给定数中低b位的数字,在汇编中使用的算法是利用与操作用一个探测数从最低位与指定数与,结果为1即说明该位为1,重复此操作直到循环结束,其中res存放结果,ptr为探测数,左移操作在这里使用自加实现,循环结束返回res即可

lab2:a variant of the fibonacci sequence

int16_t lab2(int16_t p, int16_t q, int16_t n) {// initializeint16_t R1 = p-1, R2 = q, R3 = n-2;int16_t R0 = 1, R4 = 1, R5 = -q, R6 = 1;// R0: F(n-2)%p  R4:F(n-1)  R6:F(n-1)%q// R1: p-1  R2:q  R3:n  R5:-q// calculationmod:R6 += R0;R3 -= 1;if(R3 < 0)     return R6;R0 = R4 & R1;R4 = R6;re:R6 += R5;if(R6>=0) goto re;R6 += R2;goto mod;// return value
}

第二个实验是计算修改过的斐波那契数,在这里我直接模拟当时汇编代码的实现,使用R0-R7共八个寄存器,其中使用if语句代替判断条件码,同样使用label标记代码段,使用goto语句实现跳转,取模操作则是与汇编中的方法相同,对于2的幂次数,使用与运算取模,不是则循环减,直至负数,再加上一个模数即可

lab3: longest duplicate substring

int16_t lab3(int16_t n, char s[]) {// initializeint16_t res = 1,temp = res;// calculationfor(int i = 0,j = 1; j <= n; i++,j++ ){if(s[i] == s[j])res++;else{if(res > temp)  temp = res;res = 1;}}// return valueif(temp>res) return temp;else return res;
}

第三个实验是统计给定字符串中最长的重复子串长度,在原汇编实现时,我使用的是双指针比较两个字符,在c中实现更便捷,在循环中使用两个变量i、j,其中i在前j在后,每次比较两者是否相同,使用res和temp记录当前重复字符的个数,由于最少一个相同字符,所以初始化为1,初始使用res记录,直到出现不同的字符,此时res置为1,判断两者的较大值,temp记录两者的较大值,最后循环结束,取两者中较大值即为结果
lab4:sort and count

void lab4(int16_t score[], int16_t *a, int16_t *b) {// initialize(*a) =0, (*b) = 0;int16_t temp;//冒泡排序for(int i = 1; i <=15; i++) {for (int j = 0; j <= 15 - i; j++) {if (score[j] > score[j + 1]) {temp = score[j];score[j] = score[j + 1];score[j + 1] = temp;}}}for(int i = 12; i <=15; i++){if (score[i] >= 85)(*a)++;else if (score[i] >= 75)(*b)++;}for(int i = 8; i<=11 ;i++)if(score[i] >= 75)(*b)++;
}

第四个实验是对给定的成绩进行排序,并统计“A,B”等级的个数,在汇编代码中,使用冒泡排序先对成绩序列进行排序,再统计前四个和前八个符合范围的个数,在排序后的第12-15个是最高的四个,其中大于等于85分的都是A,否则大于等于75的为B,而8-11是次高的四个,其中大于等于75的都是B

Result

Debug:

过程中遇到的主要问题有:
lab3中 res应该要重新设置为1,一开始设置为0导致每个的结果都少了1

else{if(res > temp)  temp = res;res = 1;}

lab4中,由于传入的参数类型为指针类型int16_t *a, int16_t *b,所以后面对其的操作应该要使用(*a) (*b),否则会出现结果溢出int16的范围问题

Test:

Judge:

将代码整理如下:

int16_t lab1(int16_t a, int16_t b) {// initializeint16_t res = 0, ptr = 1;// calculationwhile(b--){if(a&ptr)res++;ptr += ptr ;}// return valuereturn res;
}int16_t lab2(int16_t p, int16_t q, int16_t n) {// initializeint16_t R1 = p-1, R2 = q, R3 = n-2;int16_t R0 = 1, R4 = 1, R5 = -q, R6 = 1;// R0: F(n-2)%p  R4:F(n-1)  R6:F(n-1)%q// R1: p-1  R2:q  R3:n  R5:-q// calculationmod:R6 += R0;R3 -= 1;if(R3 < 0)     return R6;R0 = R4 & R1;R4 = R6;re:R6 += R5;if(R6>=0) goto re;R6 += R2;goto mod;// return value
}int16_t lab3(int16_t n, char s[]) {// initializeint16_t res = 1,temp = res;// calculationfor(int i = 0,j = 1; j <= n; i++,j++ ){if(s[i] == s[j])res++;else{if(res > temp)  temp = res;res = 1;}}// return valueif(temp>res) return temp;else return res;
}void lab4(int16_t score[], int16_t *a, int16_t *b) {// initialize(*a) =0, (*b) = 0;int16_t temp;//冒泡排序for(int i = 1; i <=15; i++) {for (int j = 0; j <= 15 - i; j++) {if (score[j] > score[j + 1]) {temp = score[j];score[j] = score[j + 1];score[j + 1] = temp;}}}for(int i = 12; i <=15; i++){if (score[i] >= 85)(*a)++;else if (score[i] >= 75)(*b)++;}for(int i = 8; i<=11 ;i++)if(score[i] >= 75)(*b)++;// calculation// return value
}

使用test文件评测结果如下,正常运行,输出正确。

在这里插入图片描述

Summary

  1. What is the difference between programming in a high-level language andprogramming in LC3 assembly language?
    高级语言可读性强,对程序员友好,提供的功能更全面更强大,适合编写较大的项目以及程序,但运行效率可能较低,而汇编语言可读性差,编写工程量大的代码时十分费劲,指令也很多而繁琐,许多细节都要程序员自己手动配置,对程序员不友好,但执行效率高

  2. What instructions do you think need to be added to LC3? (Hint: You can thinkabout the previous labs and what instructions could be added to greatly simplifythe previous programming)
    乘法指令和除法指令,这两个指令都需要通过循环以及其他各种指令来实现,如果多次用到那么程序会很臃肿并且写起来很麻烦,所以添加这个指令比较重要

  3. Is there anything you need to learn from LC3 for the high-level language you use?
    ​从LC-3,我学习到各种语言执行时机器码是如何变化的,特别是补码的运算,我觉得十分巧妙,以及左移右移实现的乘除操作,通过与运算等判断某一位的状态,这让我在写高级语言程序时能够更清楚其中的原理


http://www.ppmy.cn/news/23664.html

相关文章

Redis是如何工作的

写的很简洁易懂&#xff0c;存下来学习一下https://www.cnblogs.com/liang24/p/14208977.html

C++与Lua交互实例 -- 矩阵的加减乘除(版本二)

C与Lua交互实例 – 矩阵的加减乘除&#xff08;版本二&#xff09; TIPS&#xff1a;关于使用矩阵的加减乘除测试C与Lua的交互以及下面没讲述到的知识点可以阅读第一版&#xff1a; https://blog.csdn.net/qq135595696/article/details/128960951 同时下面两个方式矩阵的数据都…

若依框架 --- 偶发的el-select无法选择的问题

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是小童&#xff0c;Java开发工程师&#xff0c;CSDN博客博主&#xff0c;Java领域新星创作者 &#x1f4d5;系列专栏&#xff1a;前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 &#x1f4…

万里数据库加入龙蜥社区,打造基于“龙蜥+GreatSQL”的开源技术底座

近日&#xff0c;北京万里开源软件有限公司&#xff08;以下简称“万里数据库”&#xff09;及 GreatSQL 开源社区签署了 CLA&#xff08;Contributor License Agreement&#xff0c;贡献者许可协议&#xff09;&#xff0c;正式加入龙蜥社区&#xff08;OpenAnolis&#xff09…

阿里6面,成功唬住面试官拿了27K,软件测试面试也没有传说中那么难吧....

阿里的面试挺独特&#xff0c;每轮面试都没有 HR 约时间&#xff0c;一般是晚上 8 点左右面试官来一个电话&#xff0c;问是否能面试&#xff0c;能的话开始面&#xff0c;不能就约一个其它时间。 全程 6 面&#xff0c;前五面技术面&#xff0c;电话面试&#xff0c;最后一面…

不要再问Spring是如何解决循环依赖了

1、什么是循环依赖&#xff1f; 循环依赖主要来次三个方面&#xff0c;第一种A相互依赖&#xff0c;第二种是 A依赖B&#xff0c;B依赖A&#xff0c;第三种是A依赖B&#xff0c;B依赖C&#xff0c;C依赖A。 总结一句话就是对象之间形成环形依赖。 代码如下&#xff1a; 第一…

【个人作品】非侵入式智能开关

一、产品简介 一款可以通过网络实现语音、APP、小程序控制&#xff0c;实现模拟手动操作各种开关的非侵入式智能开关作品。 非侵入式&#xff0c;指的是不需要对现有的电路和开关做任何改动&#xff0c;只需要将此设备使用魔术无痕胶带固定在旁边即可。 以下为 ABS 材质的渲…

15.面向对象程序设计

文章目录面向对象程序设计15.1OOP&#xff1a;概述继承动态绑定15.2定义基类和派生类15.2.1定义基类成员函数与继承访问控制与继承15.2.2定义派生类派生类对象及派生类向基类的类型转换派生类构造函数派生类使用基类的成员继承与静态成员派生类的声明被用作基类的类防止继承的发…