[翻译] PDP-8 指令集简介

翻译自http://www.faqs.org/faqs/dec-faq/pdp8/section-3.html

近期因为考虑买一台PDP-8复刻机(如“PiDP-8/I” —— 一台核心是树莓派的PDP-8/I复刻,卖的就是情怀满满的前面板)摆在宿舍做装饰而看了一些关于PDP-8的资料。因为国内这款机器的爱好者较少,更找不到中文的资料,而外文的资料有一大堆。现在打算把这些资料一点点翻译成中文分享出来
内容大致会涵盖 PDP-8的体系结构,PDP-8汇编(MACRO-8),PDP-8操作系统(如OS/8),PDP-8常用高等语言(如FOCAL,4K FORTRAN这些),当然不知道要到何时才能填完

这次翻译的这篇文章讲解了PDP-8基础处理器组件的寄存器安排以及其指令集,略有涉及IO部分
不过本文并没有对每一条指令详细的解释,所以大家粗略阅读,有个大体印象即可,
我有时间会尝试翻译Douglas W. Jones 写的《PDP-8 Programmer's Reference Manual》中的详细介绍。

(题图来自PiDP-8/I项目主页,有兴趣的话可以在这里购买)

PDP-8的字长是12位,基本的内存大小是4096字(Word)。最基本的处理器部分(注:当时CPU的范围很模糊)提供以下几个寄存器:

值得一提的是,很多通常被认为需要通过寄存器进行的操作,如程序段(procedure)的连接,寻址,在PDP-8上都是在内存部分直接完成的

指令字的编码如下:

PDP-8的寻址过程比较复杂
除了要在程序计数器中的前5位中给出当前页的号码,如果要进行间接寻址,还要在内存的8~15号绝对地址按照递增顺序保存间接地址。内存中的这些位置,尽管在内存中,也被称作“自动寻址寄存器”(Auto-index register)

基础的指令包括:

ISZ和其他具有“跳过”功能的指令指的都是跳过指令序列里的下一条指令。
ISZ这条指令常被用于“循环计数器+1,并在循环完成时跳出循环”这样的场合(译注:之所以设计成累加到溢出使得结果为0,而不是递减到0,译者猜测是为了省略“递减”指令的实现,以此来减小硬件规模),同时也可以作为一般的“+1”指令使用,只需让下一条指令为空指令(no-op),或确保累加结果不会等于0即可。

执行JMS指令时返回的地址会被保存在子程序相对地址0的字中,然后开始执行由子程序相对地址1开始的程序码。返回是通过执行在子程序末尾的一个相对跳转实现的。
子程序通常通过修改自己的返回地址以实现内联参数表内寻址,或者条件性地跳过原JMS后的几条指令。

IOT系列指令遵循以下格式:

一条IOT指令可以对最多64个设备中的一个执行8种指令中的一种。习惯性地(不是普适性地),op部分的每一位都只对应该设备的一种操作。亦可以以从右到左的形式编码八种操作。
这种习惯的由来是:在PDP-8/E前,电气层面对op部分的解读有很大的限制:这些指令是以IOP脉冲形式发出的,每一位对应IO总线中的一条线,所以IO设备在解读op部分时,当时常规的做法是一条线对应一个功能,000总是表示什么也不做,111总是表示把设备支持的全部三个功能依次执行。

举一个使用IOT指令的例子:“操作终端”人机界面
在早期的PDP-8系统里,常用的终端设备是ASR33电传打字机外加一台低速纸带读取/打孔器。这两个设备通常安装在地址03(键盘输入/纸带读取)和04(电传打字/纸带打孔):

当有一个字符的输入时,键盘标记位被置1。
KCC指令在清除键盘标记位的同时还会清空AC。
KRS指令在执行时使用8位输入数据填充AC的低8位。
程序中最常用的KRB指令等效于KCC与KRS的“或”运算:在有8位输入数据时,使用KSF确认标记位为1,并用KRB读取该数据

----分隔符---

电传打字机标记位在TPC操作完成时被置1(因此,为了让系统正常运行,许多程序会在程序开头输出一个空字符,好让一切正常运行)
TCF指令会清除标记位,
TPC指令将AC中的低8位通过电传打字机输出。
程序中常用的TLS指令相当于TCF和TPC的“或”运算:在输出数据时,先用TSF确认标记位为1,然后用TLS输出一个字符

IOT指令亦可用于向硬盘/磁带这种“块型设备”进行一次“间断性数据转移”(data break transfer)。
所谓“间断性数据转移”,是过去数年间DEC对“循环窃取式直接内存存取”的别称

处理器的一些功能要通过IOT指令访问,其中一个例子是中断系统:

当有一个外部设备的标记位被置1时,就会触发一次中断。
按下终端上的“主清除”按键(master clear switch),可以清空所有的标记位并屏蔽中断
从效果上来说,触发一条中断等效于在通过JMS指令跳转到位置0的同时屏蔽中断。
中断子程序应当先检验外部设备的标记位,并且执行复位该设备的指令,并跟在返回的间接跳转指令前插入一条ION指令。因为ION指令的执行有延迟,在跳转指令被执行前中断系统会保持被屏蔽的状态。

可选内存管理模块同样需要通过IOT指令操作,该模块允许在执行内存操作时通过额外加入3位地址数据来获得高达32K的主内存寻址空间。
该模块有两种扩展寻址的指令:一条用于直接寻址,另一条用于间接寻址

另外还有一大类指令被称为“微码”(microcode)系列指令

第一组:

总的来说,上述指令可以按照对应的位将多个微码指令综合为一条指令一起执行。
组合出来的指令在执行的时候,按照上表中从上到下的顺序(CLA→RTL)依次执行。
需要注意的是,在某些机型上,不支持将IAC与R**指令组合。尝试上表以外的R**指令编码(如001)在每台机器上结果都不同,比如在PDP-8/E上,001的结果是交换AC中6个位的顺序,而在其他机型上,结果是“将除了最高两位和最低两位之外的位平移”之类的玩意。
所有的位都是0的话,会执行一条空指令(NOP)

第二组:

上述指令也可以组合,不过要注意的是这里的“与组”和“或组",SMA,SZA,SNL组合在一起,有一条成立就会跳过下一条指令;而SPA,SNA,SZL组合在一起,必须全部满足,才能跳过下一条指令。
组合出来的指令在执行的时候,按照上表中从上到下的顺序(SMA→HLT)依次执行。注意到对AC进行判断的指令排在清空AC之前,所以可以在一条指令中完成“判断AC中内容并清空AC”这种操作。
在程序中加入HLT指令是个简单粗暴地设置断点的方法,可以通过前面板进行程序修改并恢复运行。
所有的位都是0的话,会执行一条空指令(与第一组中的空指令编码不同,效果相同)

第三组:

第三组微码指令用于操作“扩展算数单元”来执行如硬件乘法,除法,24位位移,数值结果调整这些操作。
这涉及到一个额外的数据寄存器——MQ,即便没有安装MQ,也可以调用这些微码指令。
(译注:特地查阅了一些资料,EAE在PDP-8/E前并不是PDP-8的一部分,需要另行安装。关于EAE的部分以后涉及到再说(很多程序都用不到这个单元))

1 thought on “[翻译] PDP-8 指令集简介”

Leave a Reply

Your email address will not be published. Required fields are marked *