全面解析构建4位计算机:汇编语言和汇编器

描述

作为我们讨论的起点,让我们进行一个简单的思想实验。假设我们刚刚完成了4位HRRG计算机的构建。我们还假设它是地球上的第一台计算机。也就是说,没有任何其他计算机或编程语言,或者……好吧,什么都没有。

让我们宽容自己,并假设我们还开发了一些输入和输出设备-看起来像QWERTY键盘,VT100终端和纸带读/写器,并且已经将它们连接到某些HRRG上。输入和输出端口,但我们尚未创建任何代码来驱动小流氓。

在继续本专栏的其余部分之前,为什么不暂停片刻,以考虑下一步将要做什么。

用机器代码捕获和输入程序

作为一个快速提醒,HRRG具有16个寄存器并支持16条指令,如下所示(“指令集”和“指令”中对各种指令执行其魔术的方式进行了更详细的讨论。权衡”列)。

cpu

HRRG的CPU寄存器和指令。(来源:马克斯·麦克菲尔德(Max Maxfield)

我们的首要任务是创建一个非常非常简单的程序,以确保该野兽完全起作用。如果我们决定使用铅笔和纸来捕获该程序的意图并绘制带有相关注释的流程图,这不会让我感到惊讶,如下所示:

cpu

一个简单程序的流程图。(来源:马克斯·麦克菲尔德(Max Maxfield)

下一步将是确定要加载到计算机内存中的哪些操作码和操作数,以实现我们的程序。再一次,这可能涉及铅笔和纸以及一些皱眉和头挠,结果如下所示:

cpu

简单程序的机器代码。(资料来源:马克斯·麦克菲尔德(Max Maxfield)

这种表示形式称为“机器代码”,因为它们是我们的计算机(机器)将执行(处理)的二进制代码。

最后但并非最不重要的一点是,我们希望将机器代码加载到计算机中并运行程序,但是我们将如何做呢?好吧,我们可能会构建一个开关面板并将其连接到计算机。至少,这将涉及12个拨动开关代表地址,4个拨动开关代表数据,以及几个控制开关和按钮,如下所示。

cpu

简单的HRRG开关面板(来源:Max Maxfield)

为了输入程序,我们将“ Program / Run”开关设置为“ Program”,在地址开关上设置一个地址,并在数据开关上设置一个相应的操作码或操作数,然后按“ Load”按钮以将该值加载到内存中。我们将对构成程序的所有小节重复此过程。上图显示了我们准备将$ C(跳转)操作码输入到内存位置$ 106中。

输入程序后,我们将地址开关设置为指向程序的起始地址(在本示例中为$ 100),然后将“ Program / Run”开关切换为“ Run”。

用汇编语言捕获程序

许多设计原始计算机的团队都认为,为了获得最佳结果,必须尽可能地靠近机器。也就是说,他们的理念是编写尽可能接近机器内部表示形式的程序;即机器代码。

但是,您可能想像到,以机器代码捕获和输入程序非常耗时,容易出错,并且最终会给地域带来麻烦。下一步是使用一种称为汇编语言的低级符号编程语言来捕获一个程序,在该语言中,程序的语句与计算机的机器代码指令之间存在非常强的对应关系。(英国数学家凯瑟琳·布斯(Kathleen Booth)因她在1947年开始的理论工作而发明了汇编语言的概念而受到赞誉。)

当然,拥有汇编语言与拥有汇编程序并不相同,汇编程序是指将汇编程序源代码转换为可执行机器代码的实用程序。在我们的思想实验中,我们仍处于使用铅笔和纸来捕获程序的阶段。

假设我们已经定义了HRRG汇编语言(我们将在我的下一篇专栏中更详细地考虑该语言)。在这种情况下,我们可以使用铅笔和纸以汇编语言捕获程序并将其手工汇编为机器代码。让我们考虑一下原始测试程序的情况,如下所示:

cpu

手工汇编代码(来源:Max Maxfield)

非常有用的一件事是将标签与关键指令的地址相关联,例如标记我们循环开始的LOOP标签。在浏览程序时,我们将构建标签及其地址的交叉引用表,如上图的右上角所示。

就我们的简单程序而言,我们在使用标签之前先声明了标签,这使我们的生活变得轻松。在更复杂的程序中,我们可能在声明标签之前先参考标签(例如,跳转到其标签位于程序下方的子例程)。在这种情况下,我们将对源代码执行多次遍历,其中第一遍遍使我们能够确定所有标签的地址,而第二遍遍使我们能够解析我们不知道的任何地址,时间周期。

通过我们的引导程序振作起来

这就是开始变得有趣的地方。首先,我们将创建几个简单的低级实用程序例程,以允许我们监视键盘并使用我们的纸带读取器/写入器。为此,我们可以用铅笔和纸捕获源代码,将其手工组装成机器代码,然后使用开关面板将该机器代码加载到计算机的内存中(请注意,我们可以将多个程序存储在计算机的不同区域中)。记忆)。

大约在这个时候,我们还将创建一个低级别的监视程序。这种程序提供了一个简单的用户界面(通常基于单个字符命令),以允许用户执行诸如检查和更改内存,读取或写入I / O端口以及将控制权转移到内存中其他程序的操作。再一次,将使用铅笔和纸捕获该程序,然后手工组装,并使用开关面板将其加载到计算机的内存中。

接下来,我们将创建一个简单的汇编程序,仅支持我们最终希望拥有的部分功能。和以前一样,将使用铅笔和纸捕获此简单的汇编程序,然后手工组装,然后使用开关面板将其加载到计算机的内存中。

现在我们可以摇滚了,因为我们可以使用电传打字机终端之类的功能来捕获首遍汇编程序支持的汇编语言子集中的程序,并将这些源代码程序写入纸带。接下来,我们可以使用监视程序和实用程序从纸带读取此源代码,并将其存储在计算机内存的一个区域中。然后,我们可以使用首遍汇编程序将此源代码汇编为可执行的机器代码,并将其存储在内存的另一个区域中。在这一点上,我们可以对存储在计算机内存中的可执行机器代码做两件事:

从这时起,我们的牡蛎(或龙虾,或我们选择的任何甲壳类动物)便成为现实,因为我们可以使用首过汇编程序为所有现有程序(包括监视器,低级程序)创建更复杂的版本。实用程序和汇编器本身。然后,我们可以使用更复杂的汇编器来创建一个更高级的汇编器,然后一路走走。

有趣的是,当您使用高级编程语言(例如C或C ++)编写程序时,编译器不会将其直接编译为机器代码-而是,编译器会在汇编源代码中生成程序的中间版本代码,然后将这些源代码组装成机器代码。所有这些对于普通用户都是不可见的,但是对于编译器开发人员和专业程序员而言,访问中间汇编代码可能是无价的。

交叉汇编程序和宏汇编程序

在上面的思想实验中,我们考虑了最坏的情况,其中HRRG是地球上唯一的计算机。对于后续机器的设计人员来说,事情变得容易得多,因为他们可以使用现有机器来加快速度。

例如,交叉汇编程序是一种汇编程序,可以将指令转换为用于运行该计算机的计算机以外的计算机的机器代码。我在HRRG上的同谋者EEWeb专家Joe Farr创建了一个在PC上运行的HRRG交叉汇编器,它采用HRRG的汇编语言编写程序,并生成可在HRRG上运行的可执行机器/目标代码。下面的两个图像显示了同一程序段的源代码版本和目标代码版本。

cpu

HRRG交叉汇编器源代码视图(来源:Joe Farr)

cpu

HRRG交叉汇编器目标代码视图(来源:Joe Farr)

更好的是,HRRG的汇编程序是宏汇编程序,它是可以执行宏替换和扩展的汇编程序。这使我们能够定义由一个或多个语句组成的宏,然后在程序中稍后使用这些宏名称,从而避免了必须重写语句。

举一个简单的例子,HRRG的指令集不包含HALT指令。但是,我们可以使用HRRG的汇编语言将这样的指令实现为宏,如下所示:

.MACRO HALT

OR %0010, S1

 

.ENDMACRO

现在,我们可以将前面的程序示例中的OR指令替换为HALT,这有助于使程序更易于理解。此外,我们可以将所有宏捆绑到一个单独的文件中,然后可以使用.INCLUDE指令将其导入到程序中。

编辑:hfy

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分