是第一个用机器代码编写的汇编程序吗?


41

我正在阅读《计算系统的元素:从第一原理构建现代计算机》一书,其中包含的项目涉及从布尔门到高级应用程序(按此顺序)的计算机构建。我正在处理的当前项目是使用我选择的高级语言编写汇编程序,以将Hack汇编代码转换为Hack机器代码(Hack是前几章中构建的硬件平台的名称)。尽管所有硬件都是在模拟器中构建的,但我试图假装我实际上在实际过程中仅使用当时可用的工具来构建每个级别。

就是说,这让我开始思考。使用高级语言编写我的汇编程序当然很方便,但是对于有史以来第一个(即历史上)编写的汇编程序,它不需要用机器代码编写,因为那时已经存在了?

还有一个相关的问题...今天怎么样?如果出现了全新的CPU体系结构,全新的指令集和全新的汇编语法,则如何构造汇编器?我假设您仍然可以使用现有的高级语言来为汇编程序生成二进制文件,因为如果您知道新平台的汇编语言和机器语言的语法,那么编写汇编程序的任务实际上就是文本分析任务,并且与该平台没有内在联系(即需要以该平台的机器语言编写)...这就是我能够在2012年编写我的Hack汇编程序时“作弊”并使用一些预先存在的原因的原因高级语言可以帮助我。


17
您可以随时编写交叉编译器,并使用它来为当今的新硬件生成代码。
Kerrek SB 2012年

@PersonalNexus谢谢您,我对snafu进行编辑。
yannis 2012年

1
@YannisRizos没问题,发生在我们当中最好的:)
PersonalNexus

8
可能是第一个汇编程序以汇编形式写在一张纸上。然后,可能仍要在纸上执行到机器代码的转换,并通过开关将其刻录到某种形式的ROM中,一次仅一个字。
mouviciel 2012年

我的第一台计算机是具有1KB RAM的ZX81,因此实际上是我的(很短的)机器代码程序。
user281377 2012年

Answers:


36

对于有史以来第一个编写的汇编器(即历史记录),不需要用机器代码编写

不必要。当然,汇编程序的第一个版本v0.00必须是用机器代码编写的,但它的功能不足以称为汇编程序。它甚至不支持“真实”汇编器一半的功能,但是编写其自身的下一个版本就足够了。然后,您可以用汇编语言的子集重新编写v0.00,将其称为v0.01,使用它来构建汇编程序v0.02的下一个功能集,然后使用v0.02来构建v0.03,并以此类推,直到达到v1.00。结果,只有第一个版本才会包含在机器代码中。第一个发行版本将使用汇编语言。

我已使用此技巧引导开发了模板语言编译器。我的最初版本使用的是printf语句,但是我在公司中使用的第一个版本使用的是正在处理的模板处理器。引导阶段持续了不到四个小时:我的处理器几乎不能产生有用的输出时,我就用自己的语言重新编写了该文件,对其进行了编译,并丢弃了非模板版本。


4
您还有所有阶段吗?我很想看到他们,并将它们与彼此进行比较。只是为了感受您经历的过程。
Marjan Venema 2012年

3
@MarjanVenema不,我不再拥有它们-我在1998年建造了它,并一直使用到2005年,直到我发现StringTemplate为止。当我朝着最初的可用版本工作时,我正在覆盖上一个阶段和下一个阶段。我的开发周期包括对新内容进行编码,运行代码生成器以将其自身构建在单独的目录中,diff与当前代码生成器相对应以查看生成的代码部分并未以意外的方式更改,在适当位置替换代码,以及再次运行以完成循环。
dasblinkenlight 2012年

可惜但可以理解:)感谢您描述您所做的事情(以及链接)。
Marjan Venema 2012年

3
我认为您需要保留某种引导链。机器代码=>受限ASM =>完整ASM =>某些语言。否则,如果您松开二进制文件,则可能会被拧紧。(或者您可以使用C交叉编译的版本,因为实际上并不是所有的C编译器二进制文件都会立即消失。)
edA-qa mort-ora-y 2012年

3
汇编程序必须是“实际”汇编程序的唯一“功能”是进行汇编。
Miles Rout 2014年

23

根据Wikipedia的说法,Nathaniel Rochester为IBM 701实现了首个汇编语言。(日期从Wikipedia文章中不确定,它指出Rochester于1948年加入IBM,但是另一个Wikipedia页面指出701于1952年公开发布。IBM的这一页面指出“精算设计始于2月1951年1月1日,并于一年后完成”。)

但是,David Salomon的 “ Assemblers and Loaders” (第7页)指出EDSAC也有一个汇编器:

“最早的存储程序计算机之一是1949年由Maurice Wilkes和W.Renwick在剑桥大学开发的EDSAC(电子延迟存储自动计算器)。从一开始,EDSAC就有一个名为Initial Orders的汇编器。在由一组旋转电话选择器组成的只读存储器中,它接受符号指令,每条指令由一个字母助记符,一个十进制地址和一个字母组成的第三字段组成,第三字段导致12程序员预设的常量,以便在汇编时添加到地址中。” (参考文献略去。。。)

假设我们接受“ Initial Orders”优先,那么我们有明确的证据表明第一个汇编器用机器代码实现的。

这种模式(用机器代码编写初始汇编程序)在1950年代已经很普遍了。但是,根据Wikipedia所说,“组装者是第一个自我引导的语言工具”。另请参阅本节,它说明了如何使用原始汇编程序编写的机器代码来引导以汇编语言编码的更高级的汇编程序。

如今,汇编器和编译器是用高级语言编写的,而用于新计算机体系结构的汇编器或编译器通常是在不同的体系结构上开发并交叉编译的。

(FWIW-用机器代码编写和调试非平凡的程序是一个非常费力的过程。用机器代码开发汇编器的人很可能会尽快引导到用汇编器编写的汇编器。)

有关引导编译器和汇编器的这一Wikipedia页面值得一读...如果这一切令您感到困惑。


为实际回答而不仅仅是猜测而投票。这个读起来很有意思!
JacquesB 2015年

14

我认为第一批汇编程序是用机器代码编写的,因为正如您所说,那时没有其他可用的了。

但是,今天,当全新的CPU架构问世时,我们使用了所谓的交叉编译器Cross-Compiler),它是一种编译,它不为其运行所在的体系结构生成机器代码,而是为不同的体系结构生成机器代码。

(事实上​​,正如我确定您会在阅读的书中发现的那样,绝对没有什么可以使编译器天生比在任何一种架构上更适合为运行其架构的机器代码生成机器代码。其他架构。作为编译器的创建者,您要针对哪种架构就可以了。)

因此,今天甚至有可能(至少在理论上)创建一个全新的体系结构并在其上运行高级语言编译器(使用交叉编译器在其他体系结构上进行编译),然后再为该体系结构安装汇编程序。


12

首先,“组件”写在纸上,然后手动“编译”到打孔卡上。

我的祖父正在使用ZRA1(很抱歉,页面仅以德语提供,但Google翻译尚可,您实际上可以了解到最重要的事实:D)。
操作方法是将您的代码以某种汇编语言记录在纸上,而秘书实际上将转录成打孔卡,然后将其传递给操作员,结果将在第二天早晨归还。

所有这些基本上是在程序员可以通过键盘输入数据并在屏幕上查看数据之前。


3
当我在大学读书时,他们仍然有用来编写机器代码的纸块。您在右侧编写程序,在左侧有几列,可将指令转换为十六进制。和一列为当前地址。最初的组装者实际上是人类。
Florian F

9

很难肯定对非常首次汇编(很难甚至定义是什么)。多年前,当我为缺少汇编器的机器编写一些汇编器时,我仍然使用汇编语言编写代码。然后,在我完成了一段合理的代码后,便将其手工翻译成机器代码。但是,那仍然是两个完全独立的阶段-当我编写代码时,我根本没有在机器代码级别上工作或思考。

我应该补充一点,在某些情况下,我又走了一步:我用发现更易于使用的汇编语言编写了大部分代码,然后编写了一个很小的内核(或多或少现在称为虚拟机)在目标处理器上进行解释。那是非常慢的速度(特别是在1 MHz的8位处理器上),但这无关紧要,因为它通常只运行一次(或最多运行几次)。


8

您不需要汇编程序即可将汇编语言代码手动汇编为机器代码。就像您不需要编辑器来编写汇编语言代码一样。

历史的观点

最初的汇编程序可能是用汇编语言编写的,然后手工汇编成机器代码。即使处理器没有官方的“汇编语言”,程序员也可能会在将某种伪代码转换成机器指令之前,使用某种伪代码来完成大部分编程工作。

即使在计算最早期,程序员也以某种符号表示法编写程序,然后将其转换为机器代码,然后再将其输入计算机。在奥古斯塔·阿达·金(Augusta Ada King)的案子中,她将需要将它们转换为用于巴贝奇(Babbage)的分析引擎的打孔卡,但是可惜它从未被制造出来。

个人经验

我拥有的第一台计算机是Sinclair ZX81(美国的Timex 1000)。手册的背面提供了将Z80汇编语言转换为机器代码所需的所有信息(甚至包括Z80拥有的所有奇怪的索引模式操作码)。

我会用汇编语言写一个程序(纸上),然后通过代码进行试运行。当我对自己的程序没有错误感到满意时,我会在手册背面查找每条指令,将其翻译为机器代码,并将机器代码也写在纸上。最后,我将所有机器代码指令输入到我的ZX81中,然后再将其保存到磁带并尝试运行。

如果它不起作用,我将仔细检查我的手工组装,如果翻译有误,我将修补从磁带加载的字节,然后重新保存它并再次尝试运行该程序。

根据经验,我可以告诉您,如果代码是用汇编语言编写的,则比用机器代码进行调试要容易得多,因此反汇编程序很受欢迎。即使您没有汇编程序,手工汇编也比尝试直接编写机器代码要容易出错,尽管我猜像Mel这样的Real Programmer可能会不同意。* 8')


5

那时或现在没有任何区别。您要发明一种新的编程语言,请选择一种当今可用的语言来制作第一个编译器。在一段时间内,如果这是项目的目标,则可以使用该语言创建一个编译器,然后它可以自托管。

如果您所拥有的只是铅笔和纸,并且有一些开关或打孔卡作为您使用第一个或下一个新指令集的用户界面,则您将使用一个或所有可用的项目。您很可能在纸上写了一种汇编语言,然后使用汇编器将其转换为机器代码(可能是八进制),然后在某个时候进入了机器的接口。

今天,当发明了一套全新的指令集时,没有什么不同,这取决于公司/个人,实践等。硬件工程师很有可能用verilog或vhdl进行编程,用手工编写机器程序中的前几个测试程序(可能是十六进制或二进制)。根据软件团队的进度,他们可能很快或很长时间都不会转向汇编语言,然后转向编译器。

最初的计算机不是用于创建汇编器和编译器的通用计算机。您可以通过在前一个alu的输出到下一个alu的输入之间移动一些导线来对它们进行编程。最终,您有了一个通用处理器,这样您就可以在汇编中编写汇编程序,进行手工汇编,将其作为机器代码输入,然后使用它来解析ebcdic,ascii等,然后进行自我托管。将二进制文件存储到某些介质中,您以后可以读取/加载该介质,而不必保持将开关切换到手动进给机器代码的状态。

想想打孔卡和纸胶带。您绝对可以不用翻转开关,而可以制造一台完全机械的机器,这是一种省力的设备,可以创建计算机可以读取的介质。无需像altair这样的开关来输入机器代码位,您可以送纸带或打孔卡(使用机械的,非处理器驱动的,提供内存或处理器的设备,或使用小型机器代码编写的引导加载程序)。这不是一个坏主意,因为您可以在计算机的驱动下制造出一些东西,这些东西也可以机械地生产纸带或打孔卡,然后将其送回。打孔卡的两个来源,即非计算机的机械省力设备,以及计算机驱动的机器。两者都为计算机生成“二进制文件”。


1
+1表示“汇编程序,您”。容易理解一个词的一个定义(例如,汇编程序=软件),但是您的评论确实使显而易见的事情回到了视线……“汇编过程”只是一个系统/例程,很容易由人类的汇编程序。
The111 2012年

1
人们也一直对早期计算机具有指令集的想法感到困惑。早期的计算机是用铅笔和纸具有良好数学技能的女性,也就是所谓的计算机。然后那些妇女(或特别是一位妇女)通过不使用指令集的电线连接来对神经无能为力进行编程。使用指令集进行编程非常容易。是的,很容易陷入诸如汇编程序或计算机之类的单词或术语使用中,或者很早就陷入困境。
old_timer 2012年

4

在布鲁克的计算机动物园中,有一个或两个实例,他说诸如“助记符是我们的发明,设计者仅使用数字操作码或其代码为操作码的字符”之类的东西,因此在那些机器甚至没有汇编语言。

输入程序可在前面板结束调试(对于尚未完成调试的人,这是一种设置内存的方法,您可以将一些开关设置为地址,将其他开关设置为值,然后按下一个按钮,或按下另一个按钮读取值)在很晚以后很常见。一些老计时器吹嘘他们仍然能够输入广泛使用的计算机的启动代码。

直接编写机器代码和从内存转储中读取程序的难度在很大程度上取决于机器语言,其中一些相对容易(最困难的部分是跟踪地址),x86是更糟糕的情况之一。


pdp-11甚至没有豪华的旋钮。您可以通过在8个拨动开关上输入二进制地址来更改存储,然后在16个拨动开关上输入值,然后按按钮。我实际上看到有人用这种方式修复了循环程序!
詹姆斯·安德森

2

我在1975年建造了一台计算机。它的当代技术比Altair先进得多,因为它有一个“显示器rom”,通过输入十六进制的机器代码并在视频监视器上查看该代码,我可以输入程序。 Altair必须每次使用一行开关一次输入每条机器指令。

是的,在计算机的早期,然后在个人计算机的早期,人们确实使用机器代码编写应用程序。


2

轶事:

当我学习汇编语言时,在Apple []上,ROM中包含一个名为微汇编器的程序。输入时,它会立即将汇编指令转换为字节。这意味着没有标签-如果要跳转或加载,则必须自己计算偏移量。不过,这比查找指令布局和输入十六进制值要容易得多。

毫无疑问,真正的汇编程序首先是使用微型汇编程序或其他不太完整的环境编写的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.