CPU内部的寄存器,机器代码指令集以及指令与寄存器和状态标志的交互方式都是相互交织的。
您可能还记得,我的背景爱好项目之一是构建4位HRRG计算机。在整个时间范围内,这将实现为壁挂式玻璃前木柜的集合,每个木柜都包含计算机的一部分。每个机柜的功能将通过不同的实施技术实现,包括继电器,真空管,晶体管和软糖集成电路,以及磁,机械和气动/液压产品。
我在这个项目上的“犯罪伙伴”是我的好友EEWeb专家Joe Farr。Joe致力于创建将在PC上运行的计算机的虚拟表示形式。我们希望能够在不久的将来使此HRRG仿真器可供任何人使用。同时,我目前正在讨论“野兽”的物理实现。
实话实说,这个项目已经搁置了相当长的时间。实际上,直到我的好友James“ Chewy” Vorman才在2018年底向我发送电子邮件,说他正计划建造4位计算机,并询问我是否对乔和我当时的指令集有任何想法。促使他们采取行动。
在今年年初,我在“初次通过指令集”上发布了一篇专栏文章,这几乎是乔和我在时间的迷雾中留下的东西的地方。从那时起,我们一直在反复地反复提出想法。除此之外,Joe启动并运行了仿真器后,他很快就厌倦了用机器代码编写和输入测试程序,这促使他创建了一个笨拙的HRRG终端和HRRG汇编器。
运行HRRG汇编程序的HRRG终端。(来源:乔·法尔)
当然,这不是真正的Sperry Univac Uniscope 200,它只是Joe决定将其朋友好友收藏中的一个图像用作HRRG终端的背景,该终端(在此屏幕快照中)正在运行HRRG汇编程序。当我问乔为什么选择这种设备时,他回答说有两个原因。首先是右侧的面板为他提供了足够的空间来添加7段LED,常规LED,开关,磁盘驱动器和纸带打孔器的图像(老实说,我什至没有意识到这些不是物理设备的一部分);第二个原因是他太懒了,无法在自己的车间里搜寻成堆的设备来追踪他的旧DEC VT100终端。
关键是,在创建诸如井字游戏(Tic-Tac-Toe)之类的程序时(如上面的屏幕截图所示),乔发现我们的指令集提供了比我们完全掌握的功能更多的功能(这就是我们的优势)。他还发现了一些需要“调整”以使情况变得更好的事情,例如当将INC和DEC指令应用于IX(索引)寄存器之类的12位寄存器时,它们会修改N状态标志。
因此,为了使您了解最新信息,以下内容将介绍HRRG的CPU寄存器和指令集的当前运行状态。
CPU寄存器
请记住,HRRG具有4位数据总线和12位地址总线。另外,我们使用术语nybble(或半字节)来指代4位值;同样,我们使用“ $”字符表示十六进制值(例如,$ A),使用“%”字符表示二进制值(例如,%1010)。
为了使程序保持“均值”,我们决定将用户可访问的寄存器限制为1个半字节标识符,这意味着我们将自己限制为仅16个寄存器,如下所示:
CPU寄存器(来源:Max Maxfield)
一些早期的8位CPU具有一个称为累加器(ACC)的特殊寄存器,该寄存器从内存中加载值,并存储逻辑和算术运算的任何结果。其他CPU有两个累加器ACCA和ACCCB,而其他CPU选择了一堆通用寄存器。在我们的案例中,我们决定有六个通用4位寄存器R0至R5。我们还有两个状态寄存器S0和S1。
除了物理寻址逻辑寄存器PC,SP,IX,IV和TA外,我们还有三个虚拟寄存器CV,MD和MX。我们将看到这些虚拟寄存器如何在整个时间范围内发挥其魔力。可以说我还没有在其他任何地方见过像我们的虚拟寄存器概念这样的东西。
状态寄存器
如前所述,HRRG具有两个状态寄存器S0和S1。这些寄存器的内容如下所示。
状态寄存器(来源:Max Maxfield)
大多数微处理器具有多个跳转指令,例如JMP(无条件跳转),JPN(如果为负则跳转),JPNN(如果不是负则跳转),JPZ(如果为零则跳转),JPNZ(如果不为零则跳转)等等。但是,通常只有一条JSR(跳转到子例程)指令。
对于HRRG,我们只有一对JMP(跳转)和JSR(跳转到子例程)指令。但是,正如我们将看到的,这些指令的一个很酷的事情是它们的跳转/不跳转动作可以由两个状态寄存器中任何位的0/1值控制(在这种情况下, JMP和JSR指令将两个4位状态寄存器视为单个8位寄存器)。
N,Z,C和O标志以通常的方式运行(对于初学者,我们将在以后的专栏中更详细地讨论这些标志的操作)。
I(中断屏蔽)标志的状态决定了CPU是否将看到并响应外部中断:此标志中的0表示CPU将不响应;否则标志将变为0。该标志中的1表示CPU将响应。该标志加电时包含0,由用户(即用户的程序)将其设置为1。如果CPU复位,则该标志将被清除为0。
H(停止)标志指示CPU是运行还是停止:该标志中的0表示CPU将运行;否则,CPU停止运行。该标志中的1表示CPU将停止操作。该标志加电包含0。由用户决定是否在程序控制下将其设置为1。使暂停标志返回0的唯一方法是复位CPU或外部中断唤醒CPU(假定中断屏蔽标志设置为1)。
关于状态寄存器S1的位2和3(组合的8位寄存器的位6和7)中的硬连接0和1值,如果选择了1,则JMP和JSR指令将使用这些值来实现无条件跳转,如果选择了0,则为无条件跳转(用于调试目的)。
指令集
这是开始变得有趣的地方,因为这是我们决定要支持的低级指令以及这些指令将如何与CPU寄存器和状态标志交互的地方。
指令集。(来源:马克斯·麦克菲尔德(Max Maxfield)
我知道,我知道,当您第一次看到它时,这确实有些令人生畏,但这主要是因为我们正试图将大量信息塞入一个很小的空间中。
假设我们要减少通用寄存器R3的4位内容。在这种情况下,我们的指令将包含两个半字节:$ 1 $ 3,我们可以将其写为$ 13,其中$ 1是DEC(减量)指令的操作码,而$ 3是指定寄存器R3的
现在假设我们要增加12位地址为$ 123的存储单元的4位内容。在这种情况下,生成的机器代码将是$ 0 $ E $ 1 $ 2 $ 3,我们可以将其写为$ 0E123,其中$ 0是INC(增量)指令的操作码,$ E是
作为当前的最后一个示例,让我们假设我们想将%1010的值(十六进制的$ A)移动(复制)到内存位置$ 324中。在这种情况下,生成的机器代码将为$ F $ D $ E $ A $ 3 $ 2 $ 4,我们可以将其写为$ FDEA321,其中$ F是MOV(移动)指令的操作码,$ D是
我们将在接下来的两列中回顾这些机器代码指令和等效的汇编语言(相信我,当我们开始考虑汇编语言时,情况会变得更加清晰)。目前,请仔细阅读并仔细考虑以下注意事项(其编号与上表中的编号匹配),其中对这些内容进行了非常详细的总结。
#1如果源是CPU的4位或12位物理寄存器之一,则不会有
#2如果源是存储位置(使用MD或MX虚拟寄存器指示),则
#3如果源是一个常量值(如CV虚拟寄存器所示),则如果目标是4位寄存器或存储位置,则
#4如果目标是CPU的4位或12位物理寄存器之一,则不会有
#5如果目标是内存位置(如使用MD或MX虚拟寄存器指示的),则
#6如果源是4位寄存器,则目标通常是4位寄存器或存储器位置;否则,目标将是4位寄存器或存储位置。如果源是4位寄存器,而目标是12位寄存器(PC,SP,IX,IV,TA)之一,则4位寄存器的内容将被移入(复制)到最小-目标寄存器的显着半字节(LSN);如果源是12位寄存器之一(PC,SP,IX,IV,TA),则目标通常是12位寄存器或存储器位置(请参阅注释7);如果源是12位寄存器,而目标是4位寄存器,则12位寄存器的LSN的内容将被复制到4位寄存器中。
#7如果将12位寄存器的内容复制到内存中,则目标操作数将是3个半字节字段的最低有效地址。如果将存储器的内容复制到12位寄存器中,则源操作数将是3个半字节字段的最低有效地址。
#8如果源是4位寄存器或存储器位置,则将1个半字节值压入堆栈,并且SP = SP +1;如果源是12位寄存器,则将3个半字节值压入堆栈,并且SP = SP + 3;按下PUSH之后,堆栈指针将递增。
#9如果源是一个常数值,则源操作数将是1个半字节值,该值将被压入堆栈,并且SP = SP + 1(在PUSH之后堆栈指针将递增)。
#10如果目标是4位寄存器或内存位置,则SP = SP – 1且将向堆栈弹出一个1字节的值(即,堆栈指针将在POP之前递减)。如果目标是一个12位寄存器,则将从堆栈中弹出一个3位值(以SP = SP – 3结尾)。
#11没有RTS(“从子程序返回”)或RTI(“从中断返回”)指令–通过使用POP指令从堆栈中检索返回地址并将其加载到PC中,可以达到相同的效果。
#12 JMP和JSR指令后跟控制小节,然后是3小节目标地址。控制半字节用于执行无条件跳转或有条件跳转。控制半字节的最低有效三位指向由S1和S0组成的8位状态寄存器中的要测试的位;范围是000到111(0到7)。假设控制半字节的最高有效位为0,则所选状态位的值为1会导致跳转;否则,该值将变为1。例如,JMP%0001 <目标地址>等效于“如果为零则跳转”。相比之下,控制半字节最高有效位中的1将反转跳转的操作。例如,JMP%1001 <目标地址>等同于“如果不为零则跳转”。请注意,状态位7 [S1中的位3]是硬连线的1,
指令和状态寄存器
最后(并非暂时),下表总结了执行各种指令影响状态寄存器中标志的方式。
指令和状态位(来源:Max Maxfield)
您可以想象,设计计算机是一个反复的过程,事实证明,拥有Joe的仿真器是无价的。例如,只有当Joe开始编写一个播放井字游戏的程序时,我们才意识到,使用12-像IX(索引寄存器)这样的位寄存器,因此我们将其添加到规范中(在物理实现中仅包含一件事。
以下注释更详细地说明了上表的内容:
#1将目标值的最高有效位(MSB)复制到C标志中;同时,将C标志的原始内容复制到目标值的最低有效位(LSB)。
#2将目标值的最低有效位(LSB)复制到C(进位)标志;同时,将C标志的原始内容复制到目标值的最高有效位(MSB)。
#3如果比较的值相等,则Z标志设置为1,否则将其清除为0。
#4被比较的值被认为是无符号整数。如果
#5如果目标是状态寄存器S1,则将从堆栈中加载其标志,并且不会影响S0的内容;如果目标是S0,那么将从堆栈中加载其标志;如果目标是其他任何4位位置(寄存器或内存),则N和Z标志将照常运行。
#6这些标志对于4位目标照常工作,但有一个例外-如果目标是状态寄存器S0或S1之一,则S0中的标志将不会自动更新;否则,这些标志将自动更新。如果源是12位寄存器,而目标是4位寄存器,则Z和N标志将基于12位寄存器的最低有效字节的内容(即,复制);如果源是12位寄存器,而目标是存储器,则将基于整个12位寄存器的内容设置Z标志,并且将基于N位的最高有效字节的内容设置N标志。 12位寄存器。
#7将根据整个12位寄存器的内容设置Z标志,并根据12位寄存器的最高有效半字节的内容设置N标志。
编辑:hfy
-
继电器
+关注
关注
132文章
5322浏览量
148647 -
寄存器
+关注
关注
31文章
5327浏览量
120061 -
cpu
+关注
关注
68文章
10831浏览量
211215 -
计算机
+关注
关注
19文章
7434浏览量
87745
发布评论请先 登录
相关推荐
评论