上学期在大学里,我的计算机语言教师教给我们的深奥语言 空格. 。为了通过非常忙碌的日程(中期)更好地学习语言,我写了 口译员汇编器Python. 。一个 组装语言 旨在轻松促进写作课程,并且 示例程序 是用给定的组件编写的 mnemonics.

现在是夏天,一个新项目已经开始,目的是重写Whitespace 0.3的口译员和汇编器,此后进一步发展。由于比以前要在设计上工作的时间多得多,因此您在这里提供了一个大纲,为汇编语言提供了一套修订的mnemonics。这篇文章被标记为他们的讨论。

您过去曾经有过关于汇编语言的经验吗?是否有一些您认为应该将其重命名为不同的说明?您是否发现自己在盒子外面思考,并且具有与助记符命名的不同范式?如果您可以对这些问题回答是的,那么欢迎您在这里。主观答案非常感谢!


堆栈操纵(IMP:[SPACE])

堆栈操纵是最常见的操作之一,因此是IMP [Space]的短时。有四个堆栈说明。

hold N       Push the number onto the stack
copy         Duplicate the top item on the stack
copy N       Copy the nth item on the stack (given by the argument) onto the top of the stack
swap         Swap the top two items on the stack
drop         Discard the top item on the stack
drop N       Slide n items off the stack, keeping the top item

算术(imp:[tab] [space])

算术命令在堆栈上的前两个项目上运行,并将其替换为操作的结果。推动的第一项被认为是操作员的剩余。

add          Addition
sub          Subtraction
mul          Multiplication
div          Integer Division
mod          Modulo

堆访问(IMP:[TAB] [TAB])

堆访问命令查看堆栈,以找到要存储或检索的项目的地址。要存储一个项目,请按地址,然后按值运行商店命令。要检索项目,请按地址并运行检索命令,该命令将将存储的值放在堆栈顶部的位置中。

save         Store
load         Retrieve

流控制(IMP:[LF])

流控制操作也很常见。子例程以标签以及有条件和无条件跳跃的目标标记,可以实现循环。程序必须通过[LF] [LF] [LF]结束,以便解释器可以干净地退出。

L:           Mark a location in the program
call L       Call a subroutine
goto L       Jump unconditionally to a label
if=0 L       Jump to a label if the top of the stack is zero
if<0 L       Jump to a label if the top of the stack is negative
return       End a subroutine and transfer control back to the caller
halt         End the program

I/O(IMP:[TAB] [LF])

最后,我们需要能够与用户互动。有用于阅读和写作数字和单个字符的IO指令。有了这些,可以编写字符串操作例程。读取说明取堆地址可以在其中存储堆栈顶部的结果。

print chr    Output the character at the top of the stack
print int    Output the number at the top of the stack
input chr    Read a character and place it in the location given by the top of the stack
input int    Read a number and place it in the location given by the top of the stack

问题: 您如何重新设计,重写或重命名以前的助记符以及出于什么原因?

有帮助吗?

解决方案

  • 推动#N,以明确n是立即的。
  • 我认为“交换”有时是“ exc”或“ fack”。
  • “保存”通常是“ st”(商店)
  • “负载”通常是“ LD”
  • “呼叫”也可以是“ JSR”或“ BL”。
  • “ goto”通常是“ JMP”或“胸罩”
  • “如果= 0”通常为“ beq”
  • “如果<0”通常为“ blt”
  • “返回”通常是“ ret”或“ blr”
  • 在CPU的上下文中,“退出”通常是“停止”/“ HLT”。
  • “打印chr”和“ print int”可以是“ print.c”和“ print.i”。有很多方法可以指定指令变体,但通常不在操作数中。

编辑:

如果您不介意使用Ciscy语法混合操作编码和寻址模式,

  • “推(SP)”而不是“复制”
  • “按n(sp)”而不是“复制n”(Modulo乘以单词大小)
  • “推 *(sp)”而不是“加载”(除了在推动加载值之前进行pop除外)
  • “ pop *1(sp)”而不是“推”(除了它实际上弹出了两次)

另一方面,基于堆栈的代码通常将推动和弹出视为隐式。在这种情况下,“ imm n”(立即)而不是“推”。然后,所有堆栈操作都是纯粹的堆栈操作,这是一致且一致的。

我不确定我如何写“ drop n” - 说明听起来像“滴1”不等于“滴”,这似乎很奇怪。

其他提示

我认为我建议的第一个更改是更改和掉落以分别推动和弹出。

然后,也许我会将复制重命名为DUP(我认为这是以堆栈为导向的语言的最常见名称)。

我有些困惑,为什么你经常有一个简短的单词解释 不同的 到疯子。例如,助记符是保存,说明是存储。助记符是负载,解释是检索的。顺便说一句,这些是对我没有充分解释的两个助记符。保存在哪里?从哪里加载? ((编辑 随后已经编辑了这个问题,以使这些含义清楚)

感谢您的有趣帖子。

我不确定我完全理解您的问题,所以如果我不在基地,请原谅我。

除您的堆栈外,我可能还会添加一个“状态寄存器”,其中包含由算术运算符设置的各种不同标志(例如随身携带,溢出和零)。

然后,我会添加测试这些标志的“如果”表格。

我会添加位移动和旋转(左右)指令,以及和/或/XOR/NOT在位上操作的操作。

除非您打算使用I/O说明将内存视为那种出色的Turing Machine感觉的价值流,否则您很可能希望拥有某种内存访问。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top