assembly - 如何培养对 LC-3 汇编代码的直觉?
问题描述
我读到了 LC-3 是如何工作的,但我一生都无法弄清楚如何在 LC-3 程序集中进行编码。我的目标是能够编写简单的程序,例如生成斐波那契数或对数组进行排序。
有人可以指点我的资源来学习这个吗?我精通 Python 和 Java,所以这些问题背后的基本逻辑对我来说很清楚。
解决方案
学习汇编语言有几个方面,它是处理器机器代码的人类可读版本。
基本上其他语言处于逻辑级别,而机器代码非常处于物理级别
一方面,这尤其体现在存储概念上的差异:
- 逻辑变量与物理 CPU 寄存器和内存
- 逻辑变量是动态的,CPU 寄存器和内存是固定的、永久的
- 具有类型的变量与具有位的物理存储
因此,当我们编写汇编语言时,我们翻译了我们的伪代码:具有许多生命周期有限的类型变量的逻辑代码,部分是通过将逻辑变量映射到固定的物理资源上。变量通常比 CPU 寄存器多,尤其是当某些寄存器具有专用用途时,例如堆栈或返回地址。
- 逻辑变量与物理 CPU 寄存器和内存
另一方面,今天的其他语言通常采用结构化编程,而在汇编语言/机器代码中,我们有 if-goto-label。
所有结构化语句在 if-goto-label 中都有翻译。每个翻译都是将结构化形式的模式转换为 if-goto-label 形式的模式。正确地遵循模式,您将重现伪代码的控制流——在这里很容易走捷径并犯令人困惑的错误,因此我鼓励在这里采用有条不紊的方法。
其他语言有丰富的表达方式:有许多优先级的运算符,以及使用
()
's 的复杂程度。机器代码的指令(通常)最多需要 3 个操作数。函数调用、堆栈帧、参数传递、返回值是一个相当深入的主题,函数序言和结语。
- 参数需要由调用者放置到已知位置,并由被调用者从这些位置找到
- 固定的物理寄存器需要在调用者和被调用者之间共享,因此有一个协议可以进行共享。寄存器要么是调用保留的,要么是调用破坏的——每个组都适用于不同的场景,并且有自己的规则/要求才能正常工作。
- 在汇编语言中可以有一个显式的调用堆栈和堆栈指针,这是我们在 C 代码中看不到的。
- 可以有一个显式的返回地址,它应该被认为是一个参数,被调用者用来返回给正确的调用者(因为它可以动态地不同)。
- 返回值由被调用者放置到已知位置,并在返回时由调用者找到。
- 保存调用保留的寄存器、局部变量存储(例如用于数组)、参数(包括返回地址)和局部变量可以在函数调用中存在——所有这些都需要内存存储,通常以在堆栈上分配一些空间的形式(虽然有时在 LC-3 上这些是作为全局变量完成的,这意味着不支持递归)。如果堆栈空间用于其中任何一个,则该空间称为堆栈帧。
- 堆栈空间在函数序言中分配并在函数尾声中释放——这些是函数体之前和之后的函数代码部分(它们在每次函数调用时只执行一次,即使整个函数体也不会成为循环的一部分函数是一个循环)。
- 通过查找您正在使用的“调用约定”来查看更多信息,它将描述寄存器共享组、专用寄存器(例如堆栈指针)以及参数和返回值位置。
- 分析逻辑变量是否“在调用中有效”有助于选择适当的 CPU 寄存器,并告诉我们是否需要在序言中保存该寄存器并在结尾中恢复它。
有关详细信息,请参阅以下一些资源:
推荐阅读
- postgresql - 使用 Python 3 连接到 PostgreSQL 不起作用:create_engine(URL(**settings.DATABASE))
- android - Android Studio Flutter 应用程序无法在我的 Android 设备或模拟器上运行
- objective-c - 两个不同的用户保存相同的 PFObject
- r - 如果数据丢失,则在闪亮的 R 中绘制会导致错误的文本
- smart-table - 如何以编程方式清除智能表中的搜索字段?
- html - 使用智能手机摄像头从网页扫描条码
- javascript - 由于“不变违规:未找到名称输入的视图配置”,无法为 React Native 工作获得 Reactable
- java - Files.createDirectories() 抛出 FileAlreadyExistsExceptions 但没有目录
- git - 保持特定的 git 分支离线
- python - 无法在 Pycharm 中导入 numpy 或 matplotlib