微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何培养对 LC-3 汇编代码的直觉?

如何解决如何培养对 LC-3 汇编代码的直觉?

我阅读了 LC-3 的工作原理,但我终其一生都无法弄清楚如何在 LC-3 程序集中进行编码。我的目标是能够编写简单的程序,例如生成斐波那契数列或对数组进行排序。

有人可以指点我学习这个的资源吗?我精通 Python 和 Java,所以我很清楚这些问题背后的逻辑。

解决方法

学习汇编语言有几个方面,它是处理器机器代码的人类可读版本。

基本上其他语言都在逻辑层面,而机器码则在物理层面

  • 一方面,这尤其体现在存储概念上的差异:

    • 变量,即逻辑变量与物理 CPU 寄存器和内存
    • 逻辑变量是动态的,CPU 寄存器和内存是固定的、永久的
    • 具有类型的变量与具有位的物理存储

    因此,当我们编写汇编语言时,我们会翻译我们的伪代码:具有许多有限生命周期的类型变量的逻辑代码,部分是通过将逻辑变量映射到固定的物理资源上。通常有比 CPU 寄存器更多的变量,尤其是当某些寄存器具有专用用途时,例如堆栈或返回地址。

  • 另一方面,今天的其他语言通常采用结构化编程,而在汇编语言/机器代码中,我们有 if-goto-label。

    所有结构化语句在 if-goto-label 中都有翻译。每次翻译都是将结构化形式的模式转换为 if-goto-label 形式的模式。正确地遵循这些模式,您将重现伪代码的控制流 - 在这里很容易走捷径并犯下令人困惑的错误,因此我鼓励这里采用有条不紊的方法。

  • 其他语言具有丰富的表达式:具有多种优先级的运算符,并且可以根据您的喜好使用 () 的复杂程度。机器代码的指令(通常)最多接受 3 个操作数。

  • 函数调用、堆栈帧、参数传递、返回值是一个相当深的主题,函数序言和结尾。

    • 参数需要由调用者放置到已知位置,并由被调用者从这些位置找到
    • 固定的物理寄存器需要在调用者和被调用者之间共享,因此有一个协议来进行这种共享。寄存器要么保留调用,要么调用破坏 - 每个组都适用于不同的场景,并且有自己的规则/要求才能正常工作。
    • 在汇编语言中可以有一个我们在 C 代码中看不到的带有堆栈指针的显式调用堆栈。
    • 可以有一个明确的返回地址,它应该被认为是一个参数,被调用者使用它返回到正确的调用者(因为它可以动态地不同)。
    • 返回值由被调用者放置在已知位置,并在返回时由调用者找到。
    • 保存调用保留寄存器、局部变量存储,例如对于数组,参数(包括返回地址)和局部变量可以在函数调用中存活——所有这些东西都需要内存存储,通常以在堆栈上分配一些空间的形式(尽管有时在 LC-3 上完成了这些)作为全局变量,这意味着不支持递归)。如果堆栈空间用于其中任何一个,则该空间称为堆栈帧。
      • 堆栈空间在函数序言中分配并在函数尾声中释放——这些是函数体之前和之后的函数代码部分(每次函数调用它们只执行一次,它们从不属于循环,即使整个函数体是一个循环)。
    • 通过查找您正在使用的“调​​用约定”查看更多信息,其中将描述寄存器共享组、专用寄存器(例如堆栈指针)以及参数和返回值位置。
    • 分析一个逻辑变量是否“跨调用存活”有助于选择合适的 CPU 寄存器,并告诉我们是否需要在序言中保存该寄存器并在尾声中恢复它。

有关更多信息,请参阅以下一些资源:

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。