哪种类型的汇编程序跳转指令最有用?

Which type of assembler jump instruction is most useful?

我正在从事一个业余爱好项目,旨在设计一个小型 CPU 和围绕它的微型计算机系统。我有一个基本的数据流,并且已经对 ISA 中的字长和指令数做出了一些决定。我已经决定使用一个带有 4 位操作码字段的 16 位字。这允许 16 条指令。

编辑: 一些附加信息

指令字,16位,格式如下: OOOOPPPPPPPPPPPP

O 位是操作码,P 位是有效载荷,address/data。这允许 4096 千字的地址 space 和 16 个操作码。限制为 16 个操作码是一项旨在简化硬件实现的设计决策。

该架构有一个累加器(A 寄存器)、一个 B 寄存器和一个堆栈指针。

/结束编辑

ISA 具有移动和加载指令 (Load/store)、基本算术和逻辑(加、减、与非)、基本堆栈功能(压入和弹出)。还有一个子程序(无条件)jump/return 对指令。尽管如此,仍然缺少一件:条件跳转。

return函数可以和无条件跳转一样,所以我需要的是某种测试和在该测试条件下跳转。

所以,这是我的问题:最有用的 test/conditional 对是什么?

操作码中还有一个测试和一个条件跳转的空间 table,或者如果您以某种方式在其他操作(如 ADD 或 SUB)中包含条件测试,则可以进行两次条件跳转。

溢出时跳转,不是零,零,进位,不是进位是我的一些想法,但我不确定哪个更有用。任何建议表示赞赏。

(我从事汇编编程已有 40 多年;实际上早在 1970 年代初期就设计并构建了生产型多寄存器 16 位机器)。真正有用的是 CMP 指令和指定该条件的 JMP 相关指令。

我建议你让算术指令为

生成状态位
  • 零结果
  • 从结果进位
  • 结果符号
  • (签名)溢出

我们称它们为 "condition bits"。你会发现它们都很有用。

你的比较指令基本上应该做一个减法,然后丢弃答案,设置条件位。

您的 JMP 指令应使用 16 个操作码之一、一个 3 位条件 -selector 和一个与 PC 的 9 位相对偏移量,例如,相对于 PC 的跳转条件。简短的相对分支在代码中非常有用。

3 位条件 select 或者应该使用两位 select 4 个条件之一,一位 select "invert"。这样你就可以有"jmp zero"、"jmp not zero"等

您可能会将 "jump no overflow" 视为 "jump always";这些在代码中非常方便。 (我不明白你怎么认为 "jmp unconditional" 和 "return from subroutine" 可以是同一条指令)。

从讨论中的评论来看,您似乎没有任何寄存器。从代码紧凑性(尤其是 16 位指令)和性能(寄存器总是比内存访问速度更快)的角度来看,这是一个严重的错误。我会使用操作码后剩余的 2 位或 3 位或 12 位来命名寄存器。

啊哈:在一次编辑中,OP 注意到他有 A 和 B 寄存器,可能 select 由操作码隐式编辑。我设计的机器受到 PDP-11 的启发,但有 16 个基本操作码和 8 寄存器(留下 "operand" 的 9 位),它在编码方面确实有所不同。大多数指令将这 9 位分解为寻址模式和偏移量:直接(使用第二个字作为地址)、立即(第二个字)、立即(7 位,意味着机器可以轻松处理 ASCII 文本)、间接第二个寄存器自动-增量,间接第二个寄存器自动递减,相对于第二个寄存器的短偏移量,以及相对于寄存器的第二个字偏移量。它没有堆栈,但您可以使用 auto-inc/decrement 指令简单地实现一个,因此不会有任何损失。 很高兴为它编写代码。 (它还有带陷阱的虚拟内存,以及寄存器集和 VM 映射之间的硬件上下文切换)。

虽然所有这些听起来都需要复杂的逻辑来解码,但事实并非如此。 我们设法用 ~~ 120 个所谓的 "medium scale" 芯片(每个芯片 4 个门、多路复用器、4 位加法器片等)实现了这台机器。这些天我希望你能够在一个 FPGA 中实现整个事情。

剩下两个操作码,按照你的建议,一个测试和一个条件跳转指令是个好主意。

如果你想保持4/12 opcode/operand格式,你可以把条件放在TEST中,如果TEST为真,JMP指令跳转。然后,您将有一个 12 位字段来 select 测试类型。在此字段中,您可以对任何内容进行编码:A is 0A is not 0A > 0A < BA + B overflow ... 请注意,复杂的比较会变得有点尴尬,因为它们意味着 TEST 可以执行比任何其他指令更复杂的操作,但整组简单比较仍然有意义。

示例:

LOAD_A [0x30]
LOAD_B [0x40]
TEST (SIGNED A < B)
JIF MY_ADDRESS

跳转可以是绝对12位或相对12位。很多简单的ISA实现相对地址,因为比较小,但是绝对的比较简单assemble(如果你手写程序,每次改程序都不太可能改地址)