我读过LC-3是如何工作的,但我无法在我的一生中找到如何在LC-3程序集中编码。我的目标是能够编写一些简单的程序,比如生成斐波纳契数或对数组进行排序。
有人能指点我学习这方面的资源吗?我精通Python和Java,所以我很清楚这些问题背后的逻辑。
发布于 2021-03-21 18:46:29
学习汇编语言有几个方面,这是处理器机器代码的人类可读的版本。
基本上,其他语言处于逻辑级别,而机器代码则处于物理级别。
例如,
- Variables, which are logical vs. CPU registers and memory which are physical- Logical variables are dynamic, CPU registers and memory are fixed, permanent
- Variables, which have types vs. physical storage having bits因此,当我们编写汇编语言时,我们翻译我们的伪代码:具有大量类型变量的有限生命周期的逻辑代码,部分是通过将逻辑变量映射到固定的物理资源上。通常情况下,变量比CPU寄存器更多,特别是当某些寄存器具有专用用途时,比如堆栈或返回地址。
另一方面,今天的其他语言通常采用结构化编程,而在汇编语言/机器代码中,我们使用的是if-goto标签。
所有结构化语句都有if-goto-label格式的翻译。每一次转换都是将结构化形式的模式转换为if-goto-标签形式的模式。正确地遵循模式,您将复制伪代码的控制流--很容易在这里选择捷径并犯令人困惑的错误,因此我鼓励在这里采用有条不紊的方法。--
()的.()的.机器代码具有(通常)最多3个操作数的指令。。
- Parameters need to be placed into known locations by the caller and found from those locations by the callee
- The fixed physical registers need to be shared between caller and callee, so there is a protocol for doing that sharing. Registers are either call preserved or call clobbered — each group is appropriate for a different scenario, and has its own rules/requirements in order to work properly.
- There can be an explicit call stack with stack pointer in assembly language that we don't see in C code.
- There can be an explicit return address, which should be thought of as a parameter, that the callee uses to return to the proper caller (as that can be different dynamically).
- Return values are placed into known locations by the callee and found there by the caller upon return.
- Saving call-preserved registers, local variable storage e.g. for arrays, and parameters (including the return address) and local variables can be live across a function call — all these things need memory storage, usually in the form of some space allocated on the stack (though sometimes on LC-3 these are done as global variables, which means recursion is not supported). If stack space is used for any of these, that space is called a stack frame.
- Stack space is allocated in function prologue and released in function epilogue — these are sections of the function code that precede and follow the function body (they are executed only once per function invocation, they are never part of loops even if the entire body of the function is a loop).- See more information by looking for the "calling convention" you're using, which will describe the register sharing groups, dedicated registers (e.g. stack pointer), and parameter and return value locations.
- An analysis of whether a logical variable is "live across a call" helps to choose the an appropriate CPU register and tells us whether we need to save that register in prologue and restore it in epilogue.有关更多信息,请参见以下一些资源:
https://stackoverflow.com/questions/66735060
复制相似问题