跟我一起写个虚拟机 .Net 7(三)- 安装LC-3 模拟器和编译器

LC-3(Little Computer 3) 是一门教学用的虚拟计算机模型,主要是为了方便学生了解简单化的计算机结构。

主要想学习《计算机系统概论》上的案例,基本都是通过LC-3 模拟器和LC-3编译器来的,所以,把安装的方式学习一下。

这两个软件偏向于在Unix中安装,我这边没有那个环境,所以,我会把编译器安装在Ubuntu中,模拟器采用windows版的安装到本地。

官网地址

https://highered.mheducation.com/sites/0072467509/student_view0/lc-3_simulator_lab_manual.html

下载 C 3 Simulator Windows Version 3.01 (385.0K)

这个主要是模拟器,windows直接运行

htps://highered.mheducation.com/sites/dl/free/0072467509/104652/LC301.exe

下载后,双击运行

进入到安装目录

Simulate.exe 模拟器


模拟器只能打开.obj目标文件

LC3Edit.exe 编译器

可以通过以下三种方式(二进制,16进制,汇编)写代码逻辑,输出目标文件等结构


用汇编来写还是相对来讲简单的,写完之后,点击3,汇编的箭头按钮,就会保存在一个文件里,输出以下文件,当然,报错的情况下,它会提示错误。

  1. 123.asm 它是汇编文件本身
  2. 123.bin 它是二进制文件
  3. 123.hex 它是十六进制的文件
  4. 123.lst 它是程序的列表文件
  5. 123.sym 它是创建汇编的符号表
  6. 123.obj 目标文件,需要Simulate.exe 模拟器打开

下载 C to LC-3 Compiler (369.0K)

https://highered.mheducation.com/sites/dl/free/0072467509/104652/lcc.zip

解压后如下:


大概有这些东西

根据README描述,需要gcc 和 wish 和 flex ,我这边直接安装flex就会安装gcc了。

然后在当前目录执行命令

chmod +x configure
sudo apt install flex 
./configure

然后,就会显示下边这个,就成功make了,然后,开始执行安装命令

make
make install

make 执行完

make install 执行完

这个时候就会在当前文件夹下,新增一个install的文件夹,其中 lcc就是编译器了

可以通过 lcc 直接执行来看看帮助信息

./lcc

可以看到命令还是挺全的

编译C语言文件

cd 到目标路径下

cd /root/lcc-1.3/install/

然后创建一个c语言的程序,如下

int main()
{int a=1;int b=2;int c=a+b;printf("data:%d",c);return 0;
}

执行编译命令,就会生成a.asm文件,竟然有4KB大小

lcc main.c

最后可以看到很长的lc3的汇编(a.asm)

.Orig x3000
INIT_CODE
LEA R6, #-1
ADD R5, R6, #0
ADD R6, R6, R6
ADD R6, R6, R6
ADD R6, R6, R5
ADD R6, R6, #-1
ADD R5, R5, R5
ADD R5, R6, #0
LD R4, GLOBAL_DATA_POINTER
LD R7, GLOBAL_MAIN_POINTER
jsrr R7
HALTGLOBAL_DATA_POINTER .FILL GLOBAL_DATA_START
GLOBAL_MAIN_POINTER .FILL main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;main;;;;;;;;;;;;;;;;;;;;;;;;;;;;
main
ADD R6, R6, #-2
STR R7, R6, #0
ADD R6, R6, #-1
STR R5, R6, #0
ADD R5, R6, #-1ADD R6, R6, #-3
ADD R7, R4, #12
ldr R7, R7, #0
str R7, R5, #0
ADD R7, R4, #11
ldr R7, R7, #0
str R7, R5, #-1
ldr R7, R5, #0
ldr R3, R5, #-1
add R7, R7, R3
str R7, R5, #-2
ldr R7, R5, #-2
ADD R6, R6, #-1
STR R7, R6, #0
ADD R7, R4, #3
ADD R6, R6, #-1
STR R7, R6, #0
ADD R0, R4, #1
LDR R0, R0, #0
jsrr R0
LDR R7, R6, #0
ADD R6, R6, #1
ADD R7, R4, #2
ldr R7, R7, #0
lc3_L1_main
STR R7, R5, #3
ADD R6, R5, #1
LDR R5, R6, #0
ADD R6, R6, #1
LDR R7, R6, #0
ADD R6, R6, #1
RET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	void printf(const char *format, ...)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;PRINTF_PERCENT .FILL -37
PRINTF_C .FILL -99
PRINTF_D .FILL -100
PRINTF_S .FILL -115
PRINTF_B .FILL -98
PRINTF_O .FILL -111
PRINTF_X .FILL -120
PRINTF_ASCII .FILL 48 		;postive ascii value of '0'
.FILL 49
.FILL 50
.FILL 51
.FILL 52
.FILL 53
.FILL 54
.FILL 55
.FILL 56
.FILL 57
.FILL 65        ;A
.FILL 66
.FILL 67
.FILL 68
.FILL 69
.FILL 70
PRINTF_MINUS .FILL 45  
PRINTF_BUF .BLKW 18lc3_printf
ADD R6, R6, #-2
STR R7, R6, #0		;return address
ADD R6, R6, #-1
STR R5, R6, #0
ADD R5, R6, #-1ADD R6, R6, #-1
STR R4, R6, #0ADD R5, R5, #4		;cheating with the bp (no longer bp)
LDR R4, R5, #0		;got addr of format stringPRINTF_LOOP	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;LDR R0, R4, #0ADD R0, R0, #0		;End of string? (0x0000)
BRz PRINTF_DONEADD R2, R0, #0
LD R1, PRINTF_PERCENT
ADD R2, R2, R1
BRnp PRINTF_CHAR		ADD R4, R4, #1
LDR R0, R4, #0
;is it %c?
ADD R2, R0, #0
LD R3, PRINTF_C
ADD R2, R2, R3
BRnp PRINTF_CHECKSTR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%c
ADD R5, R5, #1
LDR R0, R5, #0PRINTF_CHAR
OUTADD R4, R4, #1
BRnzp PRINTF_LOOPPRINTF_CHECKSTR
;is it %s?
ADD R2, R0, #0
LD R7, PRINTF_S
ADD R2, R2, R7
BRnp PRINTF_CHECKDEC		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%sADD R5, R5, #1
LDR R0, R5, #0
PUTSADD R4, R4, #1
BRnzp PRINTF_LOOPPRINTF_CHECKDEC
;is it %d?
ADD R2, R0, #0
LD R7, PRINTF_D
ADD R2, R2, R7
;BRnp PRINTF_ERROR
BRnp PRINTF_CHECKHEXAND R2, R2, #0
ADD R2, R2, #-10		;going to divide by 10 by using sub loop
BRnzp PRINTF_NUMPRINTF_CHECKHEXADD R2, R0, #0
LD R7, PRINTF_X
ADD R2, R2, R7
BRnp PRINTF_CHECKOCTAND R2, R2, #0
ADD R2, R2, #-16		;going to divide by 10 by using sub loop
BRnzp PRINTF_NUMPRINTF_CHECKOCTADD R2, R0, #0
LD R7, PRINTF_O
ADD R2, R2, R7
BRnp PRINTF_CHECKBINAND R2, R2, #0
ADD R2, R2, #-8		;going to divide by 10 by using sub loop
BRnzp PRINTF_NUMPRINTF_CHECKBINADD R2, R0, #0
LD R7, PRINTF_B
ADD R2, R2, R7
BRnp PRINTF_ERRORAND R2, R2, #0
ADD R2, R2, #-2		;going to divide by 10 by using sub loop
;BRnzp PRINTF_NUM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%d
PRINTF_NUMLEA R7, PRINTF_BUF
ADD R7, R7, #15 
ADD R7, R7, #1 ;AND R2, R2, #0
;ADD R2, R2, #-10		;going to divide by 10 by using sub loopADD R5, R5, #1			;acquire the binary number
LDR R0, R5, #0ADD R0, R0, #0
BRzp PRINTF_DECPOS NOT R0, R0				;make num positive for sub loop
ADD R0, R0, #1PRINTF_DECPOSAND R3, R3, #0
ADD R3, R3, #-1PRINTF_DIVLOOP
ADD R3, R3, #1			;num/10 
ADD R0, R0, R2			;R0 = num % 10 - 10
BRzp PRINTF_DIVLOOPADD R3, R3, #0
BRz PRINTF_LASTDIGIT;LD R1, PRINTF_ASCII
;ADD R1, R1, R0
;NOT R2, R2
;ADD R1, R1, R2 
;ADD R1, R1, #1
;NOT R2, R2
;;;;;ADD R1, R1, #10
;STR R1, R7, #0
;ADD R7, R7, #-1			;stored ascii value of one digitLEA R1, PRINTF_ASCII
ADD R1, R1, R0
NOT R2, R2
ADD R1, R1, R2 
ADD R1, R1, #1
NOT R2, R2
LDR R1, R1, #0
STR R1, R7, #0
ADD R7, R7, #-1			;stored ascii value of one digitADD R0, R3, #0			;num/10BRnzp PRINTF_DECPOSPRINTF_LASTDIGIT;LD R1, PRINTF_ASCII
;ADD R1, R1, R0
;ADD R1, R1, #10
;STR R1, R7, #0LEA R1, PRINTF_ASCII
ADD R1, R1, R0
NOT R2, R2
ADD R1, R1, R2 
ADD R1, R1, #1
NOT R2, R2
LDR R1, R1, #0
STR R1, R7, #0			;stored ascii value of highest order digitLDR R0, R5, #0
ADD R0, R0, #0
BRzp PRINTF_DECSTRINGLD R0, PRINTF_MINUS		;num was negative
ADD R7, R7, #-1
STR R0, R7, #0			;stored ascii value negative signPRINTF_DECSTRING		;print the calculated string
ADD R0, R7, #0
PUTSADD R4, R4, #1
BRnzp PRINTF_LOOPPRINTF_ERROR
PRINTF_DONELDR R4, R6, #0		;restore R4
ADD R6, R6, #1LDR R5, R6, #0		;restore bp
ADD R6, R6, #1LDR R7, R6, #0		;restore ret addr
ADD R6, R6, #1RETGLOBAL_DATA_START
L1_main .FILL lc3_L1_main
printf .FILL lc3_printf
L5_main .FILL #0
L4_main .STRINGZ "data:%d"
L3_main .FILL #2
L2_main .FILL #1
.END

终于看到完整能输出lc3汇编的方式了。

错误情况处理

//Cannot locate make binary. 那就是缺少 make 库
sudo apt install make -y

直接通过LC-3编辑器执行这个 a.asm 文件,会发现有这样的错误


目前查找的资料是说它未发现这些符号。

可执行的汇编

.ORIG		X3000AND	R0,R0,#0;AND	R1,R1,#0;AND	R2,R2,#0;AND	R3,R3,#0;AND 	R4,R4,#0;AND 	R5,R5,#0;AND 	R6,R6,#0;AND	R7,R7,#0;初始化寄存器ADD	R5,R5,#15;ADD	R5,R5,#1;外层循环16次LD	R2,SCORE2;指向存成绩空间
OUTLOOP		ADD	R6,R6,#15;内层循环15次LD	R3,SCORE;指针指向成绩	LDR	R0,R3,#0;假设第一位为最大值,存入R0NOT	R0,R0;ADD	R0,R0,#1;R0最大值求补数
LOOP1		ADD	R3,R3,#1;指针指向下一个数字	LDR	R1,R3,#0;R1存入对比数字ADD	R4,R0,R1;R1>R0,将R0设为新的最大值R1,否则继续BRp	SWAP;将最大值设置为当前查询数ADD	R6,R6,#-1;BRz	GOOUT;内层循环结束,跳出二层循环BRnzp	LOOP1;
SWAP		AND	R0,R0,#0;NOT	R1,R1;ADD	R1,R1,#1;R1最大值求补数ADD	R0,R0,R1;	ADD	R6,R6,#-1;BRz	GOOUT;内层循环结束,跳出二层循环	BRnzp	LOOP1;
GOOUT		LD	R7,SCORE;遍历成绩表,与最大值相等的数据设置为-1。
LOOP2		LDR	R1,R7,#0;ADD	R1,R1,R0;BRz	SET;ADD	R7,R7,#1;ADD	R1,R1,#0;BRnp	LOOP2;
SET		LD	R1,MINUS1;删除当前轮最大值(设置为-1)STR	R1,R7,#0;NOT	R0,R0;ADD	R0,R0,#1;R0为当前轮最大值ADD	R2,R2,#1;STR	R0,R2,#0;ADD	R7,R7,#1;ADD	R5,R5,#-1;BRp	OUTLOOP;	BRZ	END;END		AND	R0,R0,#0;AND	R1,R1,#0;AND	R2,R2,#0;AND	R3,R3,#0;AND 	R4,R4,#0;AND 	R5,R5,#0;AND 	R6,R6,#0;AND	R7,R7,#0;初始化寄存器ADD	R1,R1,#4;遍历1-4名成绩,判断是否为ALD	R2,SCORE2;将指针指向第一名成绩ADD	R2,R2,#1;LD	R6,EIGHTYFIVE;R6存储-85LOOP		LDR	R0,R2,#0;R0存储当前查询成绩ADD	R4,R0,R6;检查当前成绩是否大于绝对分数85分,若大于R5=1,小于R5=0BRzp	OVERABSOLUTE;AND	R5,R5,#0;BRnzp	NEXT2;
OVERABSOLUTE	AND	R5,R5,#0;ADD	R5,R5,#1;
NEXT2		ADD	R5,R5,#-1;R5等于1,条件满足,为A,等于0,条件不满足,进行下一轮测试BRn	NO;
YES		ADD	R7,R7,#1;R7记录A等人数,加一ADD	R2,R2,#1;指针指向下一位成绩ADD	R1,R1,#-1;循环次数减一BRp	LOOP;BRz	END1;
NO		ADD	R2,R2,#1;指针指向下一位成绩ADD	R1,R1,#-1;循环次数减一BRp	LOOP;BRz	END1;
END1		STI	R7,GRADEA;将R7数据存入x4100LD	R2,SCORE2;ADD	R2,R2,#1;ADD	R2,R2,R7;将指针指向第N+1名成绩NOT	R7,R7;ADD	R7,R7,#1;ADD	R7,R7,#8;AND	R1,R1,#0;ADD	R1,R1,R7;遍历N+1-8名成绩,判断是否为B,循环次数8-n存入R1		AND	R6,R6,#0;LD	R6,SEVENTYFIVE;R6存储-75AND	R7,R7,#0;人数统计归零LOOP0		LDR	R0,R2,#0;R0存储当前查询成绩ADD	R4,R0,R6;检查当前成绩是否大于绝对分数75分,若大于R5=1,小于R5=0BRzp	OVERABSOLUTE1;AND	R5,R5,#0;BRnzp	NO1;
OVERABSOLUTE1	AND	R5,R5,#0;ADD	R5,R5,#1;
NEXT4		ADD	R5,R5,#-1;R5等于1,条件满足,为B,等于0,条件不满足,默认为CBRn	NO1;
YES1		ADD	R7,R7,#1;R7记录A等人数,加一ADD	R2,R2,#1;指针指向下一位成绩ADD	R1,R1,#-1;循环次数减一BRp	LOOP0;BRz	END2;
NO1		ADD	R2,R2,#1;指针指向下一位成绩ADD	R1,R1,#-1;循环次数减一BRp	LOOP0;BRz	END2;
END2		STI	R7,GRADEB;将R7数据存入x4101HALT;
SCORE		.fill	x3200;
SCORE2		.FILL	X3FFF;
GRADEA		.fill	x4100;
GRADEB		.fill	x4101;
EIGHTYFIVE	.fill	#-85;
SEVENTYFIVE	.fill	#-75;
MINUS1		.FILL	#-1;
.END;

可以先执行这个汇编和借用其中的方式方法。我大致看了,它没有使用直接编译的方式,而是直接手写汇编实现。

里面很多C语言里的函数都找不到标签,所以,相当于一些函数类的,无法搞定。对于学习也是够的了。

总结

至此 LC-3 模拟器和编辑器以及编译器都安装完了,还挺麻烦的,找了很多资料,相对而言,还是有点老了。

引用

参考了《深圳大学CS本科课程资源共享》,感谢大佬的作业。

https://github.com/Alex-Shen1121/SZU_Learning_Resource

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/111059.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库管理-第111期 Oracle Exadata 02-硬件构成(20231017)

数据库管理-第111期 Oracle Exadata 02-硬件构成(202301017) 新开的坑,感觉一般般,还是坚持写下去吧。 1 过去和Exadata相关的博文 这里集合汇总一下之前写过的和Exadata相关的文章: 数据库管理-第三十七期 我搞挂了…

搜维尔科技:“虚实结合” 体验式人机验证技术,助力通用汽车开启研发新篇章

虚拟现实(VR)技术为制造业带来了巨大的可能性。它使工程师能够以真实世界的比例完整体验他们的设计,就像身临其境一样。通过在VR中模拟制造过程,可以发现并解决许多问题,从而避免在实际生产中投入大量资源后才发现问题。VR模拟使不同团队之间的沟通和协作变得比较直观和高效。这…

解决方案|智能制造升级,汽车行业借力法大大电子签进入“快车道”

《“十四五”智能制造发展规划》明确智能制造是制造强国建设的主攻方向,其发展程度直接关乎我国制造业质量水平。发展智能制造对于巩固实体经济根基、建成现代化产业体系、实现新型工业化具有重要作用。 规划明确指出要深入实施智能制造工程,着力提升创…

零基础如何学习自动化测试

现在很多测试人员有些急于求成,没有任何基础想当然的,要在一周内上手自动化测试。 在自动化的过程中时候总有人会犯很低级的问题,有语法问题,有定位问题,而且有人居然连__init__.py 文件名都弄错误,还有将…

【LeetCode】 412. Fizz Buzz

题目链接 文章目录 Python3 【O(n) O(1)】C.emplace_back() 【C 11 之后】 Python3 【O(n) O(1)】 初始版本 class Solution:def fizzBuzz(self, n: int) -> List[str]:ans []for i in range(1, n1):if i % 5 0 and i % 3 0:ans.append("FizzBuzz")elif i % …

AutoSar 学习路线

1 获取Spec 如何获取Autosar SPEC文档? 从官网获取最新的规范文档,网址:https://www.autosar.org/standards。 如果浏览器拦截, 点开高级, 点击继续访问即可。 Autosar 分Classific 和 Adaptive Platform. AUTOSAR分…

深度学习(12)之模型训练[训练集、验证集、过拟合、欠拟合]

模型训练[训练集、验证集、过拟合、欠拟合] 在不断补充训练数据集的过程中,发现纯粹增加数据集并不会使得模型效果单向地变好,如果是多目标检测模型的话,常会出现精度变低的现象本文想总结在模型训练时的一些注意事项,比如训练集…

07 创建型模式-单例模式

1.单例模式介绍 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一,此模式保证 某个类在运行期间,只有一个实例对外提供服务,而这个类被称为单例类。 2.使用单例模式要做的两件事 保证一个类只有一个实例…

vue3后台管理系统之pinia及持久化集成使用

安装依赖 pnpm i pinia 在src目录下创建store 创建大仓库 //仓库大仓库 import { createPinia } from pinia //创建大仓库 const pinia createPinia() //对外暴露:入口文件需要安装仓库 export default pinia 全局注册pinia 配置用户仓库pinia管理数据 // 创建用…

linux环境下安装jdk1.8

一.下载linux版jdk安装包 可以在官网上下载,也可以自己找一个 官网地址:https://www.oracle.com/java/technologies/downloads/#java8 我这里用的是 jdk-8u291-linux-x64.tar.gz 二. 将jdk上传到Linux机器上 我这里用的是MobaXterm,直接拖拽就可以上传…

Python学习-----Day09

一、利用装饰器来获取函数运行的时间、 #导入time模块 import timedef decorated(fn):def inner():#time.time获取函数执行的时间a time.time() # func开始的时间fn()b time.time() # func结束的时间print(f"{fn.__name__}程序运行的总数时间:{b - a}秒")return…

Qt之自定义插件(单控件,Qt设计师中使用)

文章目录 步骤1.选择项目类型2.设置项目名称3.选择合适的构建套件4.根据实际情况选择插件控件列表6.控件类生成(默认勾选项)7.构建生成项目及生成库位置(默认)8.库文件拷贝9.重启Qt查看效果 步骤 1.选择项目类型 如图选择‘其他…

CleanMyMac苹果电脑清理软件是智商税吗?最全评测价格、清理效果一次说清

这是一篇CleanMyMac最全评测!价格、清理效果一次说清,告诉你它真不是智商税! 升级Ventura系统之前,我用的是CleanMyMac X绿色版(绝不提倡这个行为)。更新到Ventura之后,之前很多绿色软件失效,浪…

Linux安装MINIO

MINIO简介MINIO目录 mkdir -p /opt/minio/data && cd /opt/minio MINIO下载 wget https://dl.minio.org.cn/server/minio/release/linux-amd64/minio MINIO授权 chmod x minio MINIO端口 firewall-cmd --zonepublic --add-port7171/tcp --permanent && firewal…

Vue笔记_插件组件_lucky-canvas抽奖转盘

文章目录 官网使用(vue2.x)[1] 下载[2] 引入[3] 使用配置项-width/height配置项-blocks配置项-prizes配置项-buttons优化案例 lucky-canvas 是一个基于 Js Canvas 的抽奖 web 前端组件,提供 大转盘和 九宫格两种抽奖界面,UI 精美,功能强大…

C++实现AC自动机,剪枝、双数组压缩字典树!详解双数组前缀树(Double-Array Trie)剪枝字典树(Patricia Trie)

代码在:github.com/becomequantum 最近研究了一下字典树,什么AC自动机,双数组压缩字典树,剪枝字典树都自己写代码实现了一下。这本该是本科学数据结构时该玩明白的东西,我到现在才会玩。本视频主要介绍一下双数组和剪…

python 深度学习 解决遇到的报错问题7

目录 一、ValueError: unsupported pickle protocol: 5 二、报错protobuf 三、AttributeError: The vocab attribute was removed from KeyedVector in Gensim 4.0.0 四、ModuleNotFoundError: No module named cartopy 五、ImportError: cannot import name COMMON_SAFE_A…

【C++】特殊类的设计(只在堆、栈创建对象,单例对象)

🌏博客主页: 主页 🔖系列专栏: C ❤️感谢大家点赞👍收藏⭐评论✍️ 😍期待与大家一起进步! 文章目录 一、请设计一个类,只能在堆上创建对象二、 请设计一个类,只能…

竞赛选题 深度学习YOLO安检管制物品识别与检测 - python opencv

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络4 Yolov55 模型训练6 实现效果7 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习YOLO安检管制误判识别与检测 ** 该项目较为新颖,适合作为竞赛课题方向&…

【C++中cin、cin.get()、cin.getline()、getline() 的区别】

文章目录 引入cin基本用法输入多个变量换行符存放在缓冲区中 cin.get()基本用法重载函数换行符残留在缓冲区中 cin.getline()基本使用重载函数换行符不会残留在缓冲区中 string 流中的 getline()总结用法总结几个输入实例输入格式输入格式输入格式输入格式 输出格式 写在最后 引…