单一指令计算机(英语:one instruction set computer,OISC)也称URISC),它是一种抽象计算机,该计算机只有一条指令。巧妙地选取这一条指令,并且给予无限的资源,单一指令计算机就能成为和其他多指令计算机一样的图灵机。在教学上,这种计算机被推荐来帮助理解计算机架构,同时,也能用它来研究计算机的结构模型。[1]
中文名
单一指令计算机
外文名
one instruction set computer缩 写
OISC
又 称
最简指令计算机
单一指令计算机机器架构
编辑
语音
在图灵完备模型中,每个存储位置可以存储任意整数,并且根据模型可能存在任意多个位置。 指令本身作为这样的整数序列驻留在存储器中。
存在一类具有基于位操作的单指令的通用计算机,例如位复制或位反转。 由于它们的内存模型是有限的,就像在真实计算机中使用的内存结构一样,这些位操作机器相当于真实计算机而不是图灵机。
当前已知的OISC大致可分为三大类:
位操纵机
Transport Triggered Architecture机器
基于算术的图灵完备机器
位操纵机:位操作机器是最简单的一类。
BitBitJump:一个名为BitBitJump的位复制机在内存中复制一位,并无条件地将执行传递给指令的一个操作数指定的地址。 该过程证明能够进行通用计算(即能够执行任何算法并解释任何其他通用机器),因为复制位可以有条件地修改随后将执行的代码。
Toga电脑:另一台称为Toga计算机的机器反转一点并根据反转结果有条件地执行执行。
多位复印机:另一位操作机器,类似于BitBitJump,同时复制几个位。在这种情况下,通过在内存中保留预定义的跳转表来解决计算普遍性的问题。
传输触发架构:传输触发架构(TTA)是一种设计,其中计算是数据传输的副作用。通常,公共地址空间内的一些存储器寄存器(触发端口)在指令引用时执行指定的操作。例如,在使用单个内存到内存复制指令的OISC中,这是通过触发在写入时执行算术和指令指针跳转的端口来完成的。
基于算术的图灵完备机:基于算术的图灵完备机器使用算术运算和条件跳转。与之前的两台通用计算机一样,这个类也是图灵完备的。该指令对整数运算,整数也可以是存储器中的地址。
基于不同的算术运算,该类有几种已知的OISC:
加法(addleq,如果小于或等于零则增加和分支)
减少(DJN,如果非零则减量和分支(跳跃))
增加(P1eq,如果等于另一个值则加1和分支)
减法(subleq,如果小于或等于则减法和分支)
单一指令计算机指令类型
编辑
语音
单指令的常见选择是:
如果小于或等于零,则减去和分支
如果否定则减去并分支
如果借用,则反向减去并跳过
移动(用作传输触发架构的一部分)
如果非零则减去和分支(SBNZ a,b,c,定义)
Cryptoleq(异构加密和未加密计算)
在给定的实现中仅使用这些指令中的一个。因此,不需要操作码来识别要执行的指令;指令的选择是机器设计中固有的,OISC通常以其使用的指令命名。上述每条指令均可用于构建图灵完备OISC。
本文仅介绍非传输触发的基于减法的指令。然而,可以使用基于其他算术运算的指令(例如,加法)来构造图灵完备机器。例如,一种称为DLN(递减和跳转,如果不为零)的变化只有两个操作数,并使用递减作为基本操作。
单一指令计算机如果不等于零减去并且分支
SBNZ a,b,c,d指令(“减去和分支,如果不等于零”)从地址b的内容中减去地址a的内容,将结果存储在地址c,然后,如果结果不是 0,将控制转移到地址d(如果结果等于零,则按顺序执行下一条指令)。
单一指令计算机如果小于或等于零减去并且分支
subleq指令(“SUbtract和分支,如果小于或EQual为零”)从地址b的内容中减去地址a的内容,将结果存储在地址b,然后,如果结果不是肯定的,则将控制转移到 地址c(如果结果为正,则按顺序执行下一条指令)。
subleq a, b, c ; Mem[b] = Mem[b] - Mem[a]
; if (Mem[b] ≤ 0) goto c
通过将第三个操作数设置为依次等于下一个指令的地址,可以抑制条件分支。 如果未写入第三个操作数,则表示存在此抑制。
使用两个操作数和一个内部累加器也可以有一种变体,其中累加器从第一个操作数指定的存储单元中减去。 结果存储在累加器和内存位置,第二个操作数指定分支地址:
subleq2 a, b ; Mem[a] = Mem[a] - ACCUM
; ACCUM = Mem[a]
; if (Mem[a] ≤ 0) goto b
尽管每个指令仅使用两个(而不是三个)操作数,但是相应地需要更多指令来实现各种逻辑操作。
单一指令计算机合成指令
只使用subleq指令就可以合成多种类型的高阶指令。
无条件分支:
JMP c
subleq Z, Z, c
可以通过重复减法进行加法,没有条件分支; 例如,以下指令导致位置a处的内容被添加到位置b处的内容:
ADD a, b
subleq a, Z
subleq Z, b
subleq Z, Z
第一条指令从位置Z(即0)处的内容中减去位置a处的内容,并将结果(在a处的内容的负数)存储在位置Z中。第二条指令从b中减去该结果,存储在 b这个差异(是原来在a和b的内容之和); 第三条指令将值0恢复为Z.
复制指令可以类似地实现; 例如,以下指令导致位置b处的内容被位置a处的内容替换,再次假设位置Z处的内容被维持为0:
MOV a,b
subleq b, b
subleq a, Z
subleq Z, b
subleq Z, Z
可以构建任何所需的算术测试。 例如,一个”分支 - 如果 - 零“服从以下指令汇编条件:
BEQ b,c
subleq b, Z, L1
subleq Z, Z, OUT
L1: subleq Z, Z
subleq Z, b, c
OUT: ...
Subleq2也可用于合成高阶指令,尽管它通常需要针对给定任务执行更多操作。例如,转换给定字节中的所有位需要不少于10个subleq2指令:
NOT a
subleq2 tmp ; tmp = 0 (tmp = temporary register)
subleq2 tmp
subleq2 minus_one ; acc = -1
subleq2 a ; a' = a + 1
subleq2 Z ; Z = - a - 1
subleq2 tmp ; tmp = a + 1
subleq2 a ; a' = 0
subleq2 tmp ; load tmp into acc
subleq2 a ; a' = - a - 1 ( = ~a )
subleq2 Z ; set Z back to 0
仿真
以下程序(以伪代码编写)模拟基于subleq的OISC的执行:
int memory[], program_counter, a, b, c
program_counter = 0
while (program_counter >= 0):
a = memory[program_counter]
b = memory[program_counter+1]
c = memory[program_counter+2]
if (a
program_counter = -1
else:
memory[b] = memory[b] - memory[a]
if (memory[b] > 0):
program_counter += 3
else:
program_counter = c
该程序假定memory[]由非负整数索引。 因此,对于subleq指令(a,b,c),程序将小于0,b小于0或执行的分支解释为c小于0作为暂停条件。 可以在下面的外部链接中找到以基于subleq的语言编写的类似解释器(即,自解释器,其可以使用subleq指令的性质所允许的自修改代码)。
编译
Oleg Mazonka编写了一个名为Higher Subleq的编译器,它将简化的C程序编译成subleq代码。[2]
单一指令计算机如果否定则减去并分支
subneg指令(“SUbtract and Branch if NEGative”),也称为SBN.
subneg a, b, c ; Mem[b] = Mem[b] - Mem[a]
; if (Mem[b]
通过将第三个操作数设置为依次等于下一个指令的地址,可以抑制条件分支。 如果未写入第三个操作数,则表示存在此抑制。
合成指令
仅使用subneg指令可以合成许多类型的高阶指令。 为简单起见,此处仅显示一条合成指令,以说明subleq和subneg之间的区别。
JMP c
subneg POS, Z, c
...
c: subneg Z, Z
其中Z和POS分别是先前设置为包含0和正整数的位置;
只有当Z最初包含0(或小于存储在POS中的整数的值)时,才能确保无条件分支。 假设Z的内容必须保持为0,则需要后续指令在分支后清除Z.
一个变体也可能有四个操作数-subneg4。 minuend和subtrahend的逆转简化了硬件的实现。 非破坏性结果简化了合成指令。
subneg4 s, m, r, j ; subtrahend, minuend, result and jump addresses
; Mem[r] = Mem[m] - Mem[s]
; if (Mem[r]
单一指令计算机如果借用则反向减去并跳过
在Reverse Subtract和Skip if Borrow(RSSB)指令中,累加器从存储器位置中减去,如果存在借位(存储器位置小于累加器),则跳过下一条指令。 结果存储在累加器和存储器位置。 程序计数器映射到内存位置0.累加器映射到内存位置1.
单一指令计算机例子
要将x设置为y减去z的值:
# First, move z to the destination location x.
RSSB temp # Three instructions required to clear acc, temp [See Note 1]
RSSB temp
RSSB temp
RSSB x # Two instructions clear acc, x, since acc is already clear
RSSB x
RSSB y # Load y into acc: no borrow
RSSB temp # Store -y into acc, temp: always borrow and skip
RSSB temp # Skipped
RSSB x # Store y into x, acc
# Second, perform the operation.
RSSB temp # Three instructions required to clear acc, temp
RSSB temp
RSSB temp
RSSB z # Load z
RSSB x # x = y - z [See Note 2]
[注1]如果存储在“temp”的值最初为负值,并且在此例程中第一个“RSSB temp”之前执行的指令借用,那么例程工作将需要四个“RSSB temp”指令。
[注2]如果存储在“z”的值最初是负值,则将跳过最终的“RSSB x”,因此例程将不起作用。
参考资料
1.
Mavaddat F, Parhami B. URISC: The Ultimate Reduced Instruction Set Computer[J]. International Journal of Electrical Engineering Education, 1988, 25(4):327-334.
2.
Mazonka O, Kolodin A. A Simple Multi-Processor Computer Based on Subleq[J]. Eprint Arxiv, 2011.