本文是對(duì)論文《The Z1: Architecture and Algorithms of Konrad Zuse’s First Computer》的中文翻譯,已征得原作者Raul Rojas的同意。感謝Rojas教授的支持與幫助,感謝在美留學(xué)的好友——鎖在英語(yǔ)方面的指導(dǎo)。本人英文和專(zhuān)業(yè)水平有限,不妥之處還請(qǐng)批評(píng)指正。
This is a translation of "The Z1: Architecture and Algorithms of Konrad Zuse's First Computer" with the permission of its author Raul Rojas. Many thanks for the kind support and help from Prof. Rojas. And thanks to my friend Suo, who's currently in the US, for helping me with my English. The translation is completed to the best of my knowledge and ability. Any comments or suggestions would be greatly appreciated.
摘要
本文首次給出了對(duì)Z1的綜合介紹,它是由德國(guó)發(fā)明家康拉德·祖思(Konrad Zuse)1936~1938年期間在柏林建造的機(jī)械式計(jì)算機(jī)。文中對(duì)該計(jì)算機(jī)的主要結(jié)構(gòu)零件、高層架構(gòu),及其組件之間的數(shù)據(jù)交互進(jìn)行了描述。Z1能用浮點(diǎn)數(shù)進(jìn)行四則運(yùn)算。從穿孔帶讀入指令。一段程序由一系列算術(shù)運(yùn)算、內(nèi)存讀寫(xiě)、輸入輸出的指令構(gòu)成。使用機(jī)械式內(nèi)存存儲(chǔ)數(shù)據(jù)。其指令集沒(méi)有實(shí)現(xiàn)條件分支。
雖然,Z1的架構(gòu)與祖思在1941年實(shí)現(xiàn)的繼電器計(jì)算機(jī)Z3十分相似,它們之間仍然存在著明顯的差異。Z1和Z3都通過(guò)一系列的微指令實(shí)現(xiàn)各類(lèi)操作,但前者用的不是旋轉(zhuǎn)式開(kāi)關(guān)。Z1用的是數(shù)字增量器(digital incrementer)和一套狀態(tài)位,它們可以轉(zhuǎn)換成作用于指數(shù)和尾數(shù)單元以及內(nèi)存塊的微指令。計(jì)算機(jī)里的二進(jìn)制零件有著立體的機(jī)械結(jié)構(gòu),微指令每次要在12個(gè)層片(layer)中指定一個(gè)使用。在浮點(diǎn)數(shù)規(guī)格化方面,沒(méi)有考慮尾數(shù)為零的異常處理,直到Z3才彌補(bǔ)了這一點(diǎn)。
文中的知識(shí)源自對(duì)祖思為Z1復(fù)制品(位于柏林德國(guó)技術(shù)博物館)所畫(huà)的設(shè)計(jì)圖、一些信件、筆記本中草圖的仔細(xì)研究。盡管這臺(tái)計(jì)算機(jī)從1989年展出至今(停運(yùn)狀態(tài)),始終沒(méi)有關(guān)于其體系結(jié)構(gòu)詳細(xì)的、高層面的闡述可尋。本文填補(bǔ)了這一空白。
1 康拉德·祖思與Z1
德國(guó)發(fā)明家康拉德·祖思在1936~1938年期間建造了他的第一臺(tái)計(jì)算機(jī)注1(1934~1935年期間做過(guò)一些小型機(jī)械線(xiàn)路的實(shí)驗(yàn))。在德國(guó),祖思被視為計(jì)算機(jī)之父,盡管他在第二次世界大戰(zhàn)期間建造的計(jì)算機(jī)在毀于火災(zāi)之后才為人所知。祖思的專(zhuān)業(yè)是夏洛騰堡工學(xué)院(Technische Hochschule Charlottenburg)(現(xiàn)今的柏林工業(yè)大學(xué))的土木工程。他的第一份工作在亨舍爾公司(Henschel Flugzeugwerke),這家公司恰巧從1933年開(kāi)始建造軍用飛機(jī)[1]。這位25歲的小年輕,負(fù)責(zé)完成生產(chǎn)飛機(jī)部件所需的一大串結(jié)構(gòu)計(jì)算。而他在學(xué)生時(shí)代,就早已開(kāi)始考慮機(jī)械化計(jì)算的可能性[2]。所以他在亨舍爾才干了幾個(gè)月就辭職,建造機(jī)械計(jì)算機(jī)去了,還開(kāi)了自己的公司,事實(shí)也正是世界上第一家計(jì)算機(jī)公司。
注1:康拉德·祖思建造計(jì)算機(jī)的精確年表,來(lái)自于他從1946年3月起手記的小本子。本子里記載著,V1建造于1936~1938年間。
在1936~1945年期間,祖思根本停不下來(lái),哪怕被兩次短期地召去前線(xiàn)。每一次都最終被召回柏林,繼續(xù)從事在亨舍爾和自己公司的工作。在這九年間,他建造了如今我們所知的6臺(tái)計(jì)算機(jī),分別是Z1、Z2、Z3、Z4,以及專(zhuān)業(yè)領(lǐng)域的S1和S2。后四臺(tái)建造于第二次世界大戰(zhàn)開(kāi)始之后。Z4是在世界大戰(zhàn)結(jié)束前的幾個(gè)月里建好的。祖思一開(kāi)始給它們的簡(jiǎn)稱(chēng)是V1、V2、V3、V4(取自實(shí)驗(yàn)?zāi)P突蛘哒f(shuō)原型(Versuchsmodell)的首字母)。戰(zhàn)爭(zhēng)結(jié)束之后,他把V改成了Z,原因很明顯譯者注。V1(也就是后來(lái)的Z1)是項(xiàng)迷人的黑科技:它是臺(tái)全機(jī)械的計(jì)算機(jī),卻沒(méi)有用齒輪表示十進(jìn)制(前個(gè)世紀(jì)的巴貝奇這么干,正在做霍爾瑞斯制表機(jī)的IBM也這么干),祖思要建的是一臺(tái)全二進(jìn)制計(jì)算機(jī)。機(jī)器基于的部件里用小桿或金屬板的直線(xiàn)移動(dòng)表示1,不移動(dòng)表示0(或者相反,因部件而異)。祖思開(kāi)發(fā)了新型的機(jī)械邏輯門(mén),并在他父母家的客廳里做出第一臺(tái)原型。他在自傳里提到了發(fā)明Z1及后續(xù)計(jì)算機(jī)背后的故事[2]。
譯者注:祖思把V改成Z,是為了避免與韋納·馮·布勞恩(Wernher von Braun)研制的火箭的型號(hào)名相混淆。
Z1身為機(jī)械,卻竟也是臺(tái)現(xiàn)代計(jì)算機(jī):基于二進(jìn)制,使用浮點(diǎn)型表示數(shù)據(jù),并能進(jìn)行四則運(yùn)算。從穿孔帶讀入程序(雖然沒(méi)有條件分支),計(jì)算結(jié)果可以寫(xiě)入(16字大小的)內(nèi)存,也可以從內(nèi)存讀出。機(jī)器周期在4Hz左右。
Z1與1941年建成的Z3十分相像,Z3的體系結(jié)構(gòu)在《Annals of the History of Computing》中已有描述[3]。然而,迄今仍沒(méi)有對(duì)Z1高層架構(gòu)細(xì)節(jié)上的闡述。最初那臺(tái)原型機(jī)毀于1943年的一場(chǎng)空襲。只幸存了一些機(jī)械部件的草圖和照片。20世紀(jì)80年代,康拉德·祖思在退休多年之后,在西門(mén)子和其他一些德國(guó)贊助商的贊助之下,建造了一臺(tái)完整的Z1復(fù)制品,今藏于柏林的技術(shù)博物館(如圖1所示)。有兩名做工程的學(xué)生幫著他完成:那幾年間,在德國(guó)欣費(fèi)爾德的自家里,他備好全套圖紙,精心繪制每一個(gè)(要從鋼板上切割出來(lái)的)機(jī)械部件,并親自監(jiān)工。Z1復(fù)制品的第一套圖紙繪制于1984年。1986年4月,祖思畫(huà)了張時(shí)間表,預(yù)期能在1987年12月完成機(jī)器的建造。1989年,機(jī)器移交給柏林博物館的時(shí)候,做了不少次運(yùn)行和算術(shù)運(yùn)算的演示。然而,Z1復(fù)制品和之前的原型機(jī)一樣,從來(lái)都不夠可靠,無(wú)法在無(wú)人值守的情況下長(zhǎng)時(shí)間運(yùn)行。甚至在揭幕儀式上就掛了,祖思花了幾個(gè)月才修好。1995年祖思去世之后,這臺(tái)機(jī)器就再?zèng)]有啟動(dòng)過(guò)。

盡管我們有了柏林的Z1復(fù)制品,命運(yùn)卻第二次同我們開(kāi)了玩笑。除了繪制Z1復(fù)制品的圖紙,祖思并沒(méi)有正兒八經(jīng)地把有關(guān)它從頭至尾的詳盡描述寫(xiě)出來(lái)(他本意想交給當(dāng)?shù)氐拇髮W(xué)來(lái)寫(xiě))。這事兒本是相當(dāng)必要的,因?yàn)槟脧?fù)制品和1938年的Z1照片對(duì)比,前者明顯地「現(xiàn)代化」了。80年代高精密的機(jī)械儀器使祖思得以在建造機(jī)器時(shí),把鋼板制成的層片排布得更加緊密。新Z1很明顯比它的前身要小得多。而且有沒(méi)有在邏輯和機(jī)械上與前身一一對(duì)應(yīng)也不好說(shuō),祖思有可能吸收了Z3及其他后續(xù)機(jī)器的經(jīng)驗(yàn),對(duì)復(fù)制品做了改進(jìn)。在1984~1989年間所畫(huà)的那套機(jī)械圖紙中,光加法單元就出現(xiàn)了至少6種不同的設(shè)計(jì)方案,散布于5~8個(gè)、最終乃至12個(gè)機(jī)械層片之間注2。祖思沒(méi)有留下詳細(xì)的書(shū)面記錄,我們也就莫名其妙。更糟糕的是,祖思既然第二次建造了Z1,卻還是沒(méi)有留下關(guān)于它綜合性的邏輯描述。他就像那些著名的鐘表匠,只畫(huà)出表的部件,不做過(guò)多闡釋——一流的鐘表匠確實(shí)也不需要過(guò)多的說(shuō)明。他那兩個(gè)學(xué)生只幫忙寫(xiě)了內(nèi)存和穿孔帶讀取器的文檔,已經(jīng)是老天有眼[4]。柏林博物館的參觀者只能看著機(jī)器里頭成千上萬(wàn)的部件驚嘆。驚嘆之余就是絕望,即使專(zhuān)業(yè)的計(jì)算機(jī)科學(xué)家,也難以設(shè)想這頭機(jī)械怪物內(nèi)部的工作機(jī)理。機(jī)器就在這兒,但很不幸,只是尸體。
注2:你可以在我們的網(wǎng)頁(yè)「Konrad Zuse Internet Archive」上找到Z1復(fù)制品的所有圖紙。

為寫(xiě)這篇論文,我們仔細(xì)研究了Z1的圖紙和祖思記事本里零散的筆記,并在現(xiàn)場(chǎng)對(duì)機(jī)器做了大量的觀察。這么多年來(lái),Z1復(fù)制品都沒(méi)有運(yùn)行,因?yàn)槔镱^的鋼板被壓彎了。我們查閱了超過(guò)1100張機(jī)器部件的放大圖紙,以及15000頁(yè)的筆記本內(nèi)容(盡管里頭只有一小點(diǎn)有關(guān)Z1的信息)。我只能看到一段計(jì)算機(jī)一部分運(yùn)作的短視頻(于幾近20年前錄制)。慕尼黑的德意志博物館收藏了祖思論文里出現(xiàn)的1079張圖紙,柏林的技術(shù)博物館則收藏了314張。幸運(yùn)的是,一些圖紙里包含著Z1中部分微指令的定義和時(shí)序,以及一些祖思一位一位手寫(xiě)出來(lái)的例子。這些例子可能是祖思用以檢驗(yàn)機(jī)器內(nèi)部運(yùn)算、發(fā)現(xiàn)bug的。這些信息猶如羅塞塔石碑,有了它們,我們得以將Z1的微指令和圖紙聯(lián)系起來(lái),和我們充分理解的繼電器計(jì)算機(jī)Z3(有全套線(xiàn)路信息[5])聯(lián)系起來(lái)。Z3基于與Z1一樣的高層架構(gòu),但仍存在一些重要差異。
本文由淺入深:首先,了解一下Z1的分塊結(jié)構(gòu)、機(jī)械部件的布局,以及祖思用到的一些機(jī)械門(mén)的例子。而后,進(jìn)一步深入Z1的核心零件:時(shí)鐘控制的指數(shù)和尾數(shù)加法單元、內(nèi)存、算術(shù)運(yùn)算的微序列器。介紹了機(jī)械零件之間如何相互作用,「三明治」式的鋼板布局如何組織計(jì)算。研究了乘除法和輸入輸出的過(guò)程。最后簡(jiǎn)要總結(jié)了Z1的歷史地位。
2 分塊結(jié)構(gòu)
Z1是一臺(tái)時(shí)鐘控制的機(jī)器。作為機(jī)械設(shè)備,其時(shí)鐘被細(xì)分為4個(gè)子周期,以機(jī)械部件在4個(gè)相互垂直的方向上的移動(dòng)來(lái)表示,如圖3所示(左側(cè)「Cycling unit」)。祖思將一次移動(dòng)稱(chēng)為一次「銜接(engagement)」。他計(jì)劃實(shí)現(xiàn)4Hz的時(shí)鐘周期,但柏林的復(fù)制品始終連1Hz(4銜接/秒)都超不過(guò)。以這速度,一次乘法運(yùn)算要耗時(shí)20秒左右。

Z1的諸多特性被后來(lái)的Z3所采用。以現(xiàn)在的眼光來(lái)看,Z1(見(jiàn)圖3)中最重要的革新如有:
基于完全的二進(jìn)制架構(gòu)實(shí)現(xiàn)內(nèi)存和處理器。
內(nèi)存與處理器分離。在復(fù)制品中,機(jī)器大約一半由內(nèi)存和穿孔帶讀取器構(gòu)成。另一半由處理器、I/O控制臺(tái)和微控制單元構(gòu)成。原Z1的內(nèi)存容量是16字,復(fù)制品是64字。
可編程:從穿孔帶讀入8比特長(zhǎng)的指令(其中2位表示操作碼譯者注、6位表示內(nèi)存地址,或者以3位表示四則運(yùn)算和I/O操作的操作碼)。因此指令只有8種:四則運(yùn)算、內(nèi)存讀寫(xiě)、從十進(jìn)制面板讀入數(shù)據(jù)、將結(jié)果寄存器里的內(nèi)容顯示到十進(jìn)制展板。
譯者注:應(yīng)是指內(nèi)存讀寫(xiě)的操作碼。
內(nèi)存和處理器中的內(nèi)部數(shù)據(jù)以浮點(diǎn)型表示。于是,處理器分為兩個(gè)部分:一部分處理指數(shù),另一部分處理尾數(shù)。位于二進(jìn)制小數(shù)點(diǎn)后面的尾數(shù)占16個(gè)比特。(規(guī)格化的浮點(diǎn)數(shù))小數(shù)點(diǎn)左邊那位永遠(yuǎn)是1,不需要存。指數(shù)占7位,以2的補(bǔ)數(shù)形式表示(-64~+63)。用額外的1個(gè)比特來(lái)存儲(chǔ)浮點(diǎn)數(shù)的符號(hào)位。所以,存儲(chǔ)器中的字長(zhǎng)為24位(16位尾數(shù)、7位指數(shù)、1位符號(hào)位)。
參數(shù)或結(jié)果為0的特殊情況(規(guī)格化的尾數(shù)無(wú)法表示,它的第一位永遠(yuǎn)是1)由浮點(diǎn)型中特殊的指數(shù)值來(lái)處理。這一點(diǎn)到了Z3才實(shí)現(xiàn),Z1及其復(fù)制品都沒(méi)有實(shí)現(xiàn)。因此,Z1及其復(fù)制品都處理不了中間結(jié)果有0的情況。祖思知道這一短板,但他留到更易接線(xiàn)的繼電器計(jì)算機(jī)上去解決。
CPU是微代碼結(jié)構(gòu)的:操作被分解成一系列微指令,一個(gè)機(jī)器周期一條微指令。微指令在算術(shù)邏輯單元(ALU)之間產(chǎn)生具體的數(shù)據(jù)流,ALU不停地運(yùn)作,每個(gè)周期都將兩個(gè)輸入寄存器里的數(shù)加一遍。
神奇的是,內(nèi)存和處理器可以分別獨(dú)立運(yùn)行:只要穿孔帶給出命令,內(nèi)存就在通信接口寫(xiě)入或讀取數(shù)據(jù)。處理器也將在執(zhí)行存取操作時(shí)在通信接口寫(xiě)入或讀取??梢躁P(guān)閉內(nèi)存而只運(yùn)行處理器,此時(shí)原本來(lái)自?xún)?nèi)存的數(shù)據(jù)將變?yōu)?。也可以關(guān)了處理器而只運(yùn)行內(nèi)存。祖思因而可以單獨(dú)調(diào)試機(jī)器的兩個(gè)部分。同時(shí)運(yùn)作時(shí),有一根連接兩者周期單元的軸將它們同步起來(lái)。
Z1的其他革新與后來(lái)Z3中體現(xiàn)出來(lái)的想法相似。Z1的指令集與Z3幾乎一樣,但它算不了平方根。Z1利用廢棄的35毫米電影膠卷作為穿孔帶。
圖3展示了Z1復(fù)制品的抽象圖。注意機(jī)器的兩個(gè)主要部分:上半部分是內(nèi)存,下半部分是處理器。每部分都有其自己的周期單元,每個(gè)周期進(jìn)一步分為4個(gè)方向上(由箭頭標(biāo)識(shí))的機(jī)械移動(dòng)。這些移動(dòng)可以靠分布在計(jì)算部件下的杠桿帶動(dòng)機(jī)器的任何部分。一次讀入一條穿孔帶上的指令。指令的持續(xù)時(shí)間各不相同。存取操作耗時(shí)一個(gè)周期,其他操作則需要多個(gè)周期。內(nèi)存地址位于8位操作碼的低6位比特中,允許程序員尋址64個(gè)地址。
如圖3所示譯者注,內(nèi)存和處理器通過(guò)彼此各單元之間的緩存進(jìn)行通信。在CPU中,尾數(shù)的內(nèi)部表示擴(kuò)到了20位:二進(jìn)制小數(shù)點(diǎn)前加兩位(以表示二進(jìn)制冪21和20),還有兩位表示最低的二進(jìn)制冪(2-17和2-18),旨在提高CPU中間結(jié)果的精度。處理器中20位的尾數(shù)可以表示21~2-18的二進(jìn)制冪。
譯者注:原文寫(xiě)的是「圖1」,我覺(jué)得是作者筆誤,應(yīng)為「圖3」。
解碼器從穿孔帶讀取器獲得指令,判斷好操作之后開(kāi)始按需控制內(nèi)存單元和處理器。(根據(jù)加載指令)將數(shù)從內(nèi)存讀到CPU兩個(gè)浮點(diǎn)數(shù)寄存器之一。再根據(jù)另一條加載指令將數(shù)從內(nèi)存讀到另一個(gè)CPU寄存器中。這兩個(gè)寄存器在處理器里可以相加、相減、相乘或相除。這類(lèi)操作既涉及尾數(shù)的相加,也涉及指數(shù)的加減(用2的補(bǔ)碼加法器)。乘除結(jié)果的符號(hào)位由與解碼器直接相連的「符號(hào)單元」處理。
穿孔帶上的輸入指令會(huì)使機(jī)器停止,以便操作人員通過(guò)撥動(dòng)機(jī)械面板上的4個(gè)十進(jìn)制位輸入數(shù)據(jù),同時(shí)通過(guò)一根小桿輸入指數(shù)和符號(hào)。而后操作員可以重啟機(jī)器。輸出指令也會(huì)使機(jī)器停止,將結(jié)果寄存器中的內(nèi)容顯示到十進(jìn)制機(jī)械面板上,待操作員按下某根小桿,機(jī)器重新運(yùn)行。
圖3中的微序列器和指數(shù)尾數(shù)加法單元共同組成了Z1計(jì)算能力的核心。每項(xiàng)算術(shù)或I/O操作都被細(xì)分為多個(gè)「階段(phases)」。而后微序列器開(kāi)始計(jì)數(shù),并在加法單元的12層機(jī)械部件中選擇相應(yīng)層片上合適的微操作。
所以舉例來(lái)說(shuō),穿孔帶上最小的程序可以是這樣的:1) 從地址1(即第1個(gè)CPU寄存器)加載數(shù)字;2) 從地址2(即第2個(gè)CPU寄存器)加載數(shù)字;3) 相加;4) 以十進(jìn)制顯示結(jié)果。這個(gè)程序因而允許操作員預(yù)先定義好一坨運(yùn)算,把Z1當(dāng)做簡(jiǎn)單的機(jī)械計(jì)算器來(lái)用。當(dāng)然,這一系列運(yùn)算可能長(zhǎng)得多:可以把內(nèi)存當(dāng)做存放常量和中間結(jié)果的倉(cāng)庫(kù),編寫(xiě)自動(dòng)化的系列運(yùn)算(在后來(lái)的Z4計(jì)算機(jī)中,做數(shù)學(xué)計(jì)算的穿孔帶能有兩米長(zhǎng))。
Z1的體系結(jié)構(gòu)可以用如下的現(xiàn)代術(shù)語(yǔ)來(lái)總結(jié):這是一臺(tái)可編程的通用浮點(diǎn)型馮·諾依曼機(jī)(處理器和內(nèi)存分離),有著只讀的外部程序,和24位、16字的存儲(chǔ)空間??梢越邮?位數(shù)的十進(jìn)制數(shù)(以及指數(shù)和符號(hào))作為輸入,然后將轉(zhuǎn)換為二進(jìn)制。可以對(duì)數(shù)據(jù)進(jìn)行四則運(yùn)算。二進(jìn)制浮點(diǎn)型結(jié)果可以轉(zhuǎn)換回科學(xué)記數(shù)法表示的十進(jìn)制數(shù),方便用戶(hù)讀取。指令中不包含條件或無(wú)條件分支。也沒(méi)有對(duì)結(jié)果為0的異常處理。每條指令拆解為機(jī)器里「硬接線(xiàn)」的微指令。微序列器規(guī)劃著微指令的執(zhí)行。在一個(gè)僅存的機(jī)器運(yùn)行的視頻中,它宛若一臺(tái)織布機(jī)。但它編織的是數(shù)字。
3 機(jī)械部件的布局
柏林的Z1復(fù)制品布局非常清晰。所有機(jī)械部件似乎都以完美的方式布放。我們先前提過(guò),對(duì)于處理器,祖思至少設(shè)計(jì)了6個(gè)版本。但是主要部件的相對(duì)位置一開(kāi)始就確定了,大致能反映原Z1的機(jī)械布局。主要有兩個(gè)部分:分別是的內(nèi)存和處理器,由縫隙隔開(kāi)(如圖3所示)。事實(shí)上,它們分別安裝在帶滾輪的桌子上,可以扯開(kāi)了進(jìn)行調(diào)試。在水平方向上,可以進(jìn)一步把機(jī)器細(xì)分為包含計(jì)算部件的上半部分和包含所有同步杠桿的下半部分。參觀者只有彎腰往計(jì)算部件下頭看才能看到Z1的「地下世界」。圖4是設(shè)計(jì)圖里的一張繪稿,展示了處理器中部分計(jì)算和同步的層片。請(qǐng)看那12層計(jì)算部件和下側(cè)區(qū)域的3層杠桿。要理解那些繪稿是有多難,這張圖紙就是個(gè)絕好的例子。上面盡管有不少關(guān)于各部件尺寸的細(xì)節(jié),但幾乎沒(méi)有其功用方面的注解。

圖5是祖思畫(huà)的Z1復(fù)制品俯視圖,展示了邏輯部件的分布,并標(biāo)注了每個(gè)區(qū)域的邏輯功能(這幅草圖在20世紀(jì)90年代公開(kāi))。在上半部分,我們可以看到3個(gè)存儲(chǔ)倉(cāng)。每個(gè)倉(cāng)在一個(gè)層片上可以存儲(chǔ)8個(gè)8比特長(zhǎng)的字。一個(gè)倉(cāng)有8個(gè)機(jī)械層片,所以總共能存64字。第一個(gè)存儲(chǔ)倉(cāng)(10a)用來(lái)存指數(shù)和符號(hào),后兩個(gè)(10b、10c)存低16位的尾數(shù)。用這樣的比特分布存放指數(shù)和尾數(shù),只需構(gòu)建3個(gè)完全一樣的8位存儲(chǔ)倉(cāng),簡(jiǎn)化了機(jī)械結(jié)構(gòu)。
內(nèi)存和處理器之間設(shè)有「緩存」(12abc),用于與處理器進(jìn)行數(shù)據(jù)交互。不能在穿孔帶上直接設(shè)常數(shù)。所有的數(shù)據(jù),要么由用戶(hù)從十進(jìn)制輸入面板(圖右側(cè)18)輸入,要么是計(jì)算機(jī)自己算得的中間結(jié)果。
圖中的所有單元都僅僅展示了最頂上的一層。切記Z1可是建得猶如一坨機(jī)械「三明治」。每一個(gè)計(jì)算層片都與其上下層片嚴(yán)格分離(每一層都有金屬的地板和天花板)。層間的通信靠垂直的小桿實(shí)現(xiàn),它們可以把移動(dòng)傳遞到上層或下層去。畫(huà)在表示計(jì)算層片的矩形之間的小圓圈就是這些小桿。矩形里那些稍大一點(diǎn)的圓圈代表邏輯操作。我們可以在每個(gè)圓圈里找見(jiàn)一個(gè)二進(jìn)制門(mén)(縱貫層片,每個(gè)圓圈最多有12個(gè)門(mén))。根據(jù)此圖,我們可以估算出Z1中邏輯門(mén)的數(shù)量。不是所有單元都一樣高,也不是所有層片都布滿(mǎn)著機(jī)械部件。保守估計(jì),共有6000個(gè)二進(jìn)制零件組成的門(mén)。

祖思在圖5中給機(jī)器的不同模塊標(biāo)上號(hào)。各模塊的作用如下:
內(nèi)存區(qū)域
- 11a:6位內(nèi)存地址的解碼器
- 11b:穿孔帶讀取器和操作碼解碼器
- 10a:7位指數(shù)和符號(hào)的存儲(chǔ)倉(cāng)
- 10b、10b:尾數(shù)小數(shù)部分的存儲(chǔ)倉(cāng)
- 12abc:加載或存儲(chǔ)操作下與處理器交互的接口
處理器區(qū)域
- 16:控制和符號(hào)單元
- 13:指數(shù)部分中兩個(gè)ALU寄存器的多路復(fù)用器
- 14ab:ALU寄存器的多路復(fù)用器,乘除法的1比特雙向移位器
- 15a:指數(shù)的ALU
- 15bc:規(guī)格化尾數(shù)的20位ALU(18位用于小數(shù)部分)
- 17:微代碼控制
- 18:右側(cè)是十進(jìn)制輸入面板,左側(cè)是輸出面板
不難想象這幅示意圖中從上至下的計(jì)算流程:數(shù)據(jù)從內(nèi)存出來(lái),進(jìn)入兩個(gè)可尋址的寄存器(我們稱(chēng)為F和G)。這兩個(gè)寄存器是沿著區(qū)域13和14ab分布的。再把它們傳給ALU(15abc)。結(jié)果回傳給寄存器F或G(作為結(jié)果寄存器),或回傳到內(nèi)存??梢允褂谩阜醋g」(從二進(jìn)制轉(zhuǎn)換為十進(jìn)制)指令將結(jié)果顯示為十進(jìn)制。
下面我們來(lái)看看各個(gè)模塊更多的細(xì)節(jié),集中討論主要的計(jì)算部件。
4 機(jī)械門(mén)
理解Z1機(jī)械結(jié)構(gòu)的最好辦法,莫過(guò)于搞懂那幾個(gè)祖思所用的二進(jìn)制邏輯門(mén)的簡(jiǎn)單例子。表示十進(jìn)制數(shù)的經(jīng)典方式一向是旋鈕表盤(pán)。把一個(gè)齒輪分為10個(gè)扇區(qū)——旋轉(zhuǎn)齒輪可以從0數(shù)到9。而祖思早在1934年就決定使用二進(jìn)制系統(tǒng)(他跟著萊布尼茲稱(chēng)之為「the dyadic system」)。在祖思的技術(shù)中,一塊平板有兩個(gè)位置(0或1)??梢酝ㄟ^(guò)線(xiàn)性移動(dòng)從一個(gè)狀態(tài)轉(zhuǎn)移到另一個(gè)狀態(tài)。邏輯門(mén)根據(jù)所要表示的比特值,將移動(dòng)從一塊板傳遞到另一塊板。這一結(jié)構(gòu)是立體的:由堆疊的平板組成,板間的移動(dòng)通過(guò)垂直放置在平板直角處的圓柱形小桿或者說(shuō)銷(xiāo)釘實(shí)現(xiàn)。
我們來(lái)看看三種基本門(mén)的例子:合取、析取、否定。其主要思想可以有多種機(jī)械實(shí)現(xiàn),而有創(chuàng)意如祖思總能畫(huà)出適應(yīng)機(jī)器立體結(jié)構(gòu)的最佳方案。圖6譯者注展示了祖思口中的「基本門(mén)(elementary gate)」?!甘箘?dòng)板(actor plate)」可以視作機(jī)器周期。這塊板循環(huán)地從右向左再向后移動(dòng)。上面一塊板含著一個(gè)數(shù)據(jù)位,起著控制作用。它有1和0兩個(gè)位置。貫穿板洞的小桿隨著平板水平移動(dòng)(自身保持垂直)。如果上面的板處于0位置,使動(dòng)板的移動(dòng)就無(wú)法傳遞給受動(dòng)板(actuated plate)(見(jiàn)圖6左)。如果數(shù)據(jù)位處于1位置,使動(dòng)板的移動(dòng)就可以傳遞給受動(dòng)板。這就是康拉德·祖思所謂的「機(jī)械繼電器」,就是一個(gè)可以閉合機(jī)械「電流」的開(kāi)關(guān)。該基本門(mén)以此將數(shù)據(jù)位拷貝到受動(dòng)板,這個(gè)數(shù)據(jù)位的移動(dòng)方向轉(zhuǎn)了90度。
譯者注:原文「Fig. 5」應(yīng)為筆誤。

圖7展示了這種平板布局的俯視圖??梢钥吹绞箘?dòng)板上的洞口。綠色的控制板可以將圓圈(小桿)拉上拉下。當(dāng)小桿處于能被使動(dòng)板扯動(dòng)的位置時(shí),受動(dòng)板(紅色)才可以左右移動(dòng)。每一張機(jī)械俯視圖右側(cè)都畫(huà)有等效的邏輯開(kāi)關(guān)。數(shù)據(jù)位能開(kāi)閉邏輯門(mén),推拉使動(dòng)板(如箭頭所示)。祖思總是習(xí)慣把開(kāi)關(guān)畫(huà)在0位置,如圖7所示。他習(xí)慣讓受動(dòng)板被使動(dòng)板推動(dòng)(圖7右),而不是拉動(dòng)(圖7左)。至此,要構(gòu)建一個(gè)非門(mén)就很簡(jiǎn)單了,只需數(shù)據(jù)位處于0時(shí)閉合、1時(shí)斷開(kāi)的開(kāi)關(guān)(如圖7底部?jī)蓮垐D所示)譯者注。
譯者注:相當(dāng)于與圖6的邏輯相反。
有了機(jī)械繼電器,現(xiàn)在可以直接構(gòu)建余下的邏輯操作了。圖8用抽象符號(hào)展示了機(jī)器中的必備線(xiàn)路。等效的機(jī)械裝置應(yīng)該不難設(shè)想。


現(xiàn)在誰(shuí)都可以構(gòu)建自己的祖思機(jī)械計(jì)算機(jī)了?;A(chǔ)零件就是機(jī)械繼電器??梢栽O(shè)計(jì)更復(fù)雜的連接(比如包含兩塊受動(dòng)板的繼電器),只是相應(yīng)的機(jī)械結(jié)構(gòu)只能用平板和小桿構(gòu)建。
構(gòu)建一臺(tái)完整的計(jì)算機(jī)的關(guān)鍵難題是把所有部件相互連接起來(lái)。注意數(shù)據(jù)位的移動(dòng)方向總是與結(jié)果位的移動(dòng)方向正交。每一次完整的邏輯操作都會(huì)將機(jī)械移動(dòng)旋轉(zhuǎn)90度。下一次邏輯操作又把移動(dòng)旋轉(zhuǎn)90度,以此類(lèi)推。四門(mén)之后,回到最初的移動(dòng)方向。這就是為什么祖思用東南西北作為周期單位。在一個(gè)機(jī)器周期內(nèi),可以運(yùn)行4層邏輯計(jì)算。邏輯門(mén)既可簡(jiǎn)單如非門(mén),也可復(fù)雜如包含兩塊受動(dòng)板(如XOR)。Z1的時(shí)鐘表現(xiàn)為,4次銜接內(nèi)完成一次加法:銜接IV加載參數(shù),銜接I和II計(jì)算部分和與進(jìn)位,銜接III計(jì)算最終結(jié)果。
輸入的數(shù)據(jù)位在某層上移動(dòng),而結(jié)果的數(shù)據(jù)位傳到了別層上去。意即,小桿可以在機(jī)器的層片之間上下傳遞比特。我們將在加法線(xiàn)路中看到這一點(diǎn)。
至此,圖5的內(nèi)涵就更豐富了:各單元里的圓圈正是祖思抽象符號(hào)里的圓圈,并反映著邏輯門(mén)的狀態(tài)?,F(xiàn)在,我們可以從機(jī)械層面拔高,站在更邏輯的高度探討Z1。
Z1的內(nèi)存
內(nèi)存是目前我們對(duì)Z1理解最透徹的部分。Schweier和Saupe曾于20世紀(jì)90年代對(duì)其有過(guò)介紹[4]。Z4——康拉德·祖思于1945年完成的繼電器計(jì)算機(jī)——使用了一種非常類(lèi)似的內(nèi)存。Z4的處理器由電話(huà)繼電器構(gòu)建,但其內(nèi)存仍是機(jī)械式的,與Z1相似。如今,Z4的機(jī)械式內(nèi)存收藏于德意志博物館。在一名學(xué)生的輔助下,我們?cè)谟?jì)算機(jī)中仿真出了它的運(yùn)作。
Z1中數(shù)據(jù)存儲(chǔ)的主要概念,就是用垂直的銷(xiāo)釘?shù)膬蓚€(gè)位置來(lái)表示比特。一個(gè)位置表示0,另一個(gè)位置表示1。下圖展示了如何通過(guò)在兩個(gè)位置之間來(lái)回移動(dòng)銷(xiāo)釘來(lái)設(shè)置比特值。

圖9(a)譯者注展示了內(nèi)存中的兩個(gè)比特。在步驟9(b)中,縱向的控制板帶著銷(xiāo)釘上移。步驟9(c)中,兩塊橫向的使動(dòng)板中,下側(cè)那塊被銷(xiāo)釘和控制板推動(dòng),上側(cè)那塊沒(méi)被推動(dòng)。步驟9(d)中,比特位移回到初始位置,而后控制板將它們移到9(a)的位置。從這樣的內(nèi)存中讀取比特的過(guò)程具有破壞性。讀取一位之后,必須靠9(d)的回移還原比特。
譯者注:作者沒(méi)有在圖中標(biāo)出abcd,左上為(a),右上為(b),左下為(c),右下為(d)。另,這組插圖有點(diǎn)抽象,我也是盯了好久才看懂,它是俯視圖,黑色的小正方形是銷(xiāo)釘,縱向的長(zhǎng)方形是控制板,銷(xiāo)釘在控制板上的長(zhǎng)方形洞里移動(dòng)(兩個(gè)位置表示0和1),橫向的兩塊帶尖齒的長(zhǎng)方形是使動(dòng)板。
通過(guò)解碼6位地址,尋址字。3位標(biāo)識(shí)8個(gè)層片,另外3位標(biāo)識(shí)8個(gè)字。每一層的解碼線(xiàn)路是一棵典型的三層繼電器二進(jìn)制樹(shù),這和Z3中一樣(只是樹(shù)的層數(shù)不同)。
我們不再深究機(jī)械式內(nèi)存的結(jié)構(gòu)。更多細(xì)節(jié)可參見(jiàn)文獻(xiàn)[4]。
Z1的加法單元
戰(zhàn)后,康拉德·祖思在一份文檔里介紹過(guò)加法單元,但Z1復(fù)制品中的加法單元與之不同。那份文檔[6]中,使用OR、AND和恒等(NOT-XOR)邏輯門(mén)處理二進(jìn)制位。而Z1復(fù)制品中,加法單元使用兩個(gè)XOR和一個(gè)AND。
前兩步計(jì)算是:a) 待相加的兩個(gè)寄存器按位XOR,保存結(jié)果;b) 待相加的兩個(gè)寄存器按位AND,保存結(jié)果。第三步就是根據(jù)前兩步計(jì)算進(jìn)位。進(jìn)位設(shè)好之后,最后一步就是對(duì)進(jìn)位和第一步XOR的結(jié)果進(jìn)行按位XOR運(yùn)算。
下面的例子展示了如何用上述步驟完成兩數(shù)的二進(jìn)制相加。

康拉德·祖思發(fā)明的計(jì)算機(jī)都使用了「預(yù)進(jìn)位」。比起在各二進(jìn)制位之間串行地傳遞進(jìn)位,所有位上的進(jìn)位可以一步完成。上面的例子就說(shuō)明了這一過(guò)程。第一次XOR產(chǎn)生不考慮進(jìn)位情況下兩個(gè)寄存器之和的中間結(jié)果。AND運(yùn)算產(chǎn)生進(jìn)位比特:進(jìn)位要傳到左邊的比特上去,只要這個(gè)比特在前一步XOR運(yùn)算結(jié)果是1,進(jìn)位將繼續(xù)向左傳遞。在示例中,AND運(yùn)算產(chǎn)生的最低位上的進(jìn)位造成了三次進(jìn)位,最后和第一次XOR的結(jié)果進(jìn)行XOR。XOR運(yùn)算產(chǎn)生的一列連續(xù)的1猶如火車(chē)頭,牽引著AND所產(chǎn)生的進(jìn)位,直到1的鏈條斷裂。
圖10所示就是Z1復(fù)制品中的加法線(xiàn)路。圖中展示了a桿和b桿這兩個(gè)比特的相加(假設(shè)a是寄存器Aa中的第i個(gè)比特,b是寄存器Ab中的第i個(gè)比特)。使用二進(jìn)制門(mén)1、2、3、4并行進(jìn)行XOR和AND運(yùn)算。AND運(yùn)算作用于5,產(chǎn)生進(jìn)位ui+1,與此同時(shí),XOR運(yùn)算用6閉合XOR的比特「鏈」,或讓它保持?jǐn)嚅_(kāi)。7是將XOR的結(jié)果傳給上層的輔助門(mén)。8和9計(jì)算最后一步XOR,完成整個(gè)加法。
箭頭標(biāo)明了各部件的移動(dòng)。4個(gè)方向都上陣了,意即,一次加法運(yùn)算,從操作數(shù)的加載到結(jié)果的生成,需要一整個(gè)周期。結(jié)果傳遞到e桿——寄存器Ae的第i位。
加法線(xiàn)路位于加法區(qū)域的第1、2、3個(gè)層片(如后頭的圖13所示)。康拉德·祖思在沒(méi)有正式受過(guò)二進(jìn)制邏輯學(xué)培訓(xùn)的情況下,就整出了預(yù)進(jìn)位,實(shí)在了不得。連第一臺(tái)大型電子計(jì)算機(jī)ENIAC采用的都只是十進(jìn)制累加器的串行進(jìn)位。哈佛的Mark I用了預(yù)進(jìn)位,但是十進(jìn)制。

5 Z1的序列器
Z1中的每一項(xiàng)操作都可以分解為一系列微指令。其過(guò)程根據(jù)一種叫做「準(zhǔn)則(criteria)」的表格實(shí)現(xiàn),如圖11所示,表格由成對(duì)放置的108塊金屬板組成(在此我們只能看到最頂上——即層片12——的一對(duì)板。剩下的位于這兩塊板下面,合共12層)。用10個(gè)比特編排表格中的條目(金屬板本身):
- 比特Op0、Op1和Op2是指令的二進(jìn)制操作碼
- 比特S0和S1是條件位,由機(jī)器的其他部分設(shè)置。舉個(gè)例子,當(dāng)S0=1時(shí),加法就轉(zhuǎn)換成了減法。
- 比特Ph0、Ph1、Ph2、Ph3、Ph4用于對(duì)一條指令中的微周期(或者說(shuō)「階段」)計(jì)數(shù)。比如,乘法運(yùn)算消耗20個(gè)階段,于是Ph0~Ph4這五個(gè)比特在運(yùn)算過(guò)程中從0增長(zhǎng)到19。
這10個(gè)比特意味著,理論上我們可以定義多達(dá)1024種不同的條件或者說(shuō)情況。一條指令最多可占32個(gè)階段。這10個(gè)比特(操作碼、條件位、階段)推動(dòng)金屬銷(xiāo)(圖11中涂灰者),這些金屬銷(xiāo)hold住微控制板以防它們彈到左邊或右邊(如圖所示,每塊板都連著彈簧)。微控制板上分布著各異的齒,這些齒決定著以當(dāng)前10根控制銷(xiāo)的位置,是否可以阻止板的彈動(dòng)。每塊控制板都有個(gè)「地址」。當(dāng)這10位控制比特指定了某塊板的地址,它便可以彈到右邊(針對(duì)圖11中上側(cè)的板)或左邊(針對(duì)圖11中下側(cè)的板)。
控制板彈到右側(cè)會(huì)按到4個(gè)條件位(A、B、C、D)。金屬板根據(jù)相應(yīng)準(zhǔn)則切割,從而按下A、B、C、D不同的組合。
由于這些板分布于機(jī)器的12個(gè)層片上, 激活一塊控制板自然也意味著為下一步的操作選好了相應(yīng)的層片。指數(shù)單元中的微操作可以和尾數(shù)單元的微操作并行開(kāi)始,畢竟兩塊板可以同時(shí)彈動(dòng):一塊向左,一塊向右。其實(shí)也可以讓兩個(gè)不同層片上的板同時(shí)朝右彈(右側(cè)對(duì)應(yīng)尾數(shù)控制),但機(jī)械上的局限限制了這樣的「并行」。

因此控制Z1,就相當(dāng)于調(diào)整金屬板上的齒,以使它們可以響應(yīng)具體的10比特組合,去作用到左右側(cè)的單元上。左側(cè)控制著處理器的指數(shù)部分。右側(cè)控制著尾數(shù)部分。選項(xiàng)A、B、C、D是互斥的,意即,微控制板只選其一(就是唯一不被按下的那個(gè))。
6 處理器的數(shù)據(jù)通路
圖12展示了Z1的浮點(diǎn)數(shù)處理器。處理器分別有一條處理指數(shù)(圖左)和一條處理尾數(shù)(圖右)的數(shù)據(jù)通路。浮點(diǎn)型寄存器F和G均由記錄指數(shù)的7個(gè)比特和記錄尾數(shù)的17個(gè)比特構(gòu)成。指數(shù)-尾數(shù)對(duì)(Af,Bf)是浮點(diǎn)寄存器F,(Ag,Bg)是浮點(diǎn)寄存器G。參數(shù)的符號(hào)由外部的一個(gè)符號(hào)單元處理。乘除結(jié)果的符號(hào)在計(jì)算前得出。加減結(jié)果的符號(hào)在計(jì)算后得出。
我們可以從圖12中看到寄存器F和G,以及它們與處理器其他部分的關(guān)系。ALU(算術(shù)邏輯單元)包含著兩個(gè)浮點(diǎn)寄存器:(Aa,Ba)和(Ab,Bb)。它們直接就是ALU的輸入,用于加載數(shù)值,還可以根據(jù)ALU的輸出Ae和Be的總線(xiàn)反饋,保存迭代過(guò)程中的中間結(jié)果。
Z1中的數(shù)據(jù)總線(xiàn)使用「三態(tài)」模式,意即,諸多輸入都可以推到同一根數(shù)據(jù)線(xiàn)(也是個(gè)機(jī)械部件)上。不需要「用電」把數(shù)據(jù)線(xiàn)和輸入分離開(kāi)來(lái),因?yàn)楦疽矝](méi)有電。因著機(jī)械部件沒(méi)有移動(dòng)(沒(méi)有推動(dòng))就代表輸入0,移動(dòng)(推動(dòng))了就代表輸入1,部件之間不存在沖突。如果有兩個(gè)部件同時(shí)往一根數(shù)據(jù)線(xiàn)上輸入,唯一重要的是確保它們能根據(jù)機(jī)器周期按序執(zhí)行(推動(dòng)只在一個(gè)方向上生效)。

程序員能接觸到的寄存器只有(Af,Bf)和(Ag,Bg)。它們沒(méi)有地址:加載指令第一個(gè)加載的寄存器是(Af,Bf),第二個(gè)加載的是(Ag,Bg)。加載完兩個(gè)寄存器,就可以開(kāi)始算術(shù)運(yùn)算了。(Af,Bf)同時(shí)還是算術(shù)運(yùn)算的結(jié)果寄存器。(Ag,Bg)在一次算術(shù)運(yùn)算之后可以隱式加載,并繼續(xù)擔(dān)當(dāng)新一輪算術(shù)運(yùn)算的第二個(gè)參數(shù)。這種寄存器的使用方案和Z3相同。但Z3中少了(Ag,Bg)。其主寄存器和輔寄存器之間的協(xié)作比Z1更復(fù)雜。
從處理器的數(shù)據(jù)通路可見(jiàn),獨(dú)立的寄存器Aa、Ab、Ba和Bb可以加載不同類(lèi)型的數(shù)據(jù):來(lái)自其他寄存器的值、常數(shù)(+1、-1、3、13)、其他寄存器的取負(fù)值、ALU反饋回來(lái)的值??梢詫?duì)ALU的輸出進(jìn)行取負(fù)值或移位操作。以代表與2n相乘的矩形框表示左移n位;以與2n相除表示右移n位。這些矩形框代表具有相應(yīng)的移位或求補(bǔ)邏輯的機(jī)械線(xiàn)路。舉個(gè)例子,寄存器Ba和Bb相加的結(jié)果存于Be,可以對(duì)其進(jìn)行多種轉(zhuǎn)換:可以取反(-Be)、可以右移一或兩位(Be/2、Be/4)、或可以左移一或三位(2Be、8Be)。每一種轉(zhuǎn)換都在組成ALU的機(jī)械層片中有著各自對(duì)應(yīng)的層片。有效計(jì)算的相關(guān)結(jié)果將傳回給寄存器Ba或Bb。具體是哪個(gè)寄存器,由微控制器指定的、激活相應(yīng)層片的小桿來(lái)指定。計(jì)算結(jié)果Be也可以直接傳至內(nèi)存單元(圖12沒(méi)有畫(huà)出相應(yīng)總線(xiàn))。
ALU在每個(gè)周期內(nèi)都進(jìn)行一次加法。ALU算完后,擦除各寄存器Aa、Ab、Ba、Bb,可載入反饋值。

寄存器Ba有一項(xiàng)特殊使命,就是將四位十進(jìn)制的數(shù)轉(zhuǎn)換成二進(jìn)制。十進(jìn)制數(shù)從機(jī)械面板輸入,每一位都轉(zhuǎn)換成4個(gè)比特。把這些4比特的組合直接傳進(jìn)Ba(2-13的位置),將第一組4比特與10相乘,下一組與這個(gè)中間結(jié)果相加,再與10相乘,以此類(lèi)推。舉個(gè)例子,假設(shè)我們想轉(zhuǎn)換8743這個(gè)數(shù),先輸入8并乘以10。然后7與這個(gè)結(jié)果相加,所得總數(shù)(87)乘以10。4再與結(jié)果(870)相加,以此類(lèi)推。如此實(shí)現(xiàn)了一種將十進(jìn)制輸入轉(zhuǎn)換為二進(jìn)制數(shù)的簡(jiǎn)單算法。在這一過(guò)程中,處理器的指數(shù)部分不斷調(diào)整最終浮點(diǎn)結(jié)果的指數(shù)。(指數(shù)ALU中常數(shù)13對(duì)應(yīng)213,后文還有對(duì)十-二進(jìn)制轉(zhuǎn)換算法的詳述。)
圖13還展示了處理器中,尾數(shù)部分?jǐn)?shù)據(jù)通路各零件的空間分布。機(jī)器最左側(cè)的模塊由分布在12個(gè)層片上的移位器構(gòu)成。寄存器Bf和Bg(層片5和層片7)直接從右邊的內(nèi)存獲得數(shù)據(jù)。寄存器Be中的結(jié)果橫穿層片8回傳至內(nèi)存。寄存器Ba、Bb和Be靠垂直的小桿存儲(chǔ)比特值(在上面這幅處理器的橫截面圖中只能看到一個(gè)比特)。ALU分布在兩摞機(jī)械上。層片1和層片2完成對(duì)Ba和Bb的AND運(yùn)算和XOR運(yùn)算。所得結(jié)果往右傳,右邊負(fù)責(zé)完成進(jìn)位以及最后一步XOR運(yùn)算,并把結(jié)果存儲(chǔ)于Be。結(jié)果Be可以回傳、存進(jìn)內(nèi)存,也可以以圖中的各方式進(jìn)行移位,并根據(jù)要求回傳給Ba或Bb。有些線(xiàn)路看起來(lái)多余(比如將Be載入Ba有兩種方式),但它們是在提供更多的選擇。層片12無(wú)條件地將Be載入Ba,層片9則僅在指數(shù)Ae為0時(shí)才這么做。圖中,標(biāo)成綠色的矩形框表示空層片,不承擔(dān)計(jì)算任務(wù),任由機(jī)械部件穿堂而過(guò)。Bf和Bf'之間的矩形框包含了Bf做乘法運(yùn)算時(shí)所需的移位器(處理時(shí)Bf中的比特從最低一位開(kāi)始逐位讀入)。

現(xiàn)在你可以想象出這臺(tái)機(jī)器里的計(jì)算流程了:數(shù)據(jù)從寄存器F和G流入機(jī)器,填入寄存器A和B。執(zhí)行一次加法或一系列的加減(以實(shí)現(xiàn)乘除)運(yùn)算。在A和B中不斷迭代中間結(jié)果直至得到最終結(jié)果。最終結(jié)果載入寄存器F,而后開(kāi)始新一輪的計(jì)算。
7 算術(shù)指令
前文提過(guò),Z1可以進(jìn)行四則運(yùn)算。在下面將要討論的表格中,約定用字母「L」表示二進(jìn)制的1。表格給出了每一項(xiàng)操作所需的一系列微指令,以及在它們的作用下處理器中寄存器之間的數(shù)據(jù)流。一張表總結(jié)了加法和減法(用2的補(bǔ)數(shù)),一張表總結(jié)了乘法,還有一張表總結(jié)了除法。關(guān)于兩種I/O操作,也有一張表:十-二進(jìn)制轉(zhuǎn)換和二-十進(jìn)制轉(zhuǎn)換。表格分為負(fù)責(zé)指數(shù)的A部分和負(fù)責(zé)尾數(shù)的B部分。表中各行顯示了寄存器Aa、Ab、Ba、Bb的加載。操作所對(duì)應(yīng)的階段,在標(biāo)「Ph」的列中給出。條件(Condition)可以在開(kāi)始時(shí)觸發(fā)或禁用某操作。某一行在執(zhí)行時(shí),增量器會(huì)設(shè)置條件位,或者計(jì)算下一個(gè)階段(Ph)。
加法/減法
下面的微指令表,既涵蓋了加法的情況,也涵蓋了減法。這兩種操作的關(guān)鍵在于,將參與加減的兩個(gè)數(shù)進(jìn)行縮放,以使其二進(jìn)制指數(shù)相等。假設(shè)相加的兩個(gè)數(shù)為m1×2a和m2×2b。如果a=b,兩個(gè)尾數(shù)就可以直接相加。如果a>b,則較小的那個(gè)數(shù)就得重寫(xiě)為m2×2b-a×2a。第一次相乘,相當(dāng)于將尾數(shù)m2右移(a-b)位(使尾數(shù)縮?。?。讓我們就設(shè)m2'=m2×2b-a。相加的兩個(gè)數(shù)就變成了m1和m2'。共同的二進(jìn)制指數(shù)為2a。a<b的情況也類(lèi)似處理。

譯者注:「Ph」原文寫(xiě)的是「cycle」,即周期,下文也有用「phase」(階段)的,根據(jù)表中信息,統(tǒng)一用「Ph」更直觀,下同。
表中(圖15),先找出兩數(shù)中較大的二進(jìn)制指數(shù),而后,較小數(shù)的尾數(shù)右移一定位數(shù),至兩者的二進(jìn)制指數(shù)相等。真正的相加從Ph4開(kāi)始,由ALU在一個(gè)Ph內(nèi)完成。Ph5中,檢測(cè)這一結(jié)果尾數(shù)是否是規(guī)格化的,如果不是,則通過(guò)移位將其規(guī)格化。(在進(jìn)行減法之后)有可能出現(xiàn)結(jié)果尾數(shù)為負(fù)的情況,就將該結(jié)果取負(fù),負(fù)負(fù)得正。條件位S3記錄著這一符號(hào)的改變,以便于為最終結(jié)果進(jìn)行必要的符號(hào)調(diào)整。最后,得到規(guī)格化的結(jié)果。
穿孔帶讀取器附近的符號(hào)單元(見(jiàn)圖5,區(qū)域16)會(huì)預(yù)先計(jì)算結(jié)果的符號(hào)以及運(yùn)算的類(lèi)型。如果我們假設(shè)尾數(shù)x和y都是正的,那么對(duì)于加減法,(在分配好符號(hào)之后)就有如下四種情況。設(shè)結(jié)果為z:
- z = +x +y
- z = +x -y
- z = -x +y
- z = -x –y
對(duì)于情況(1)和(4),可由ALU中的加法來(lái)處理。情況(1)中,結(jié)果為正。情況(4),結(jié)果為負(fù)。情況(2)和(3)需要做減法。減法的符號(hào)在Ph5(圖15)中算得。
加法執(zhí)行如下步驟:
- 在指數(shù)單元中計(jì)算指數(shù)之差?α,
- 選擇較大的指數(shù),
- 將較小數(shù)的尾數(shù)右移譯者注?α譯者注位,
- 尾數(shù)相加,
- 將結(jié)果規(guī)格化,
- 結(jié)果的符號(hào)與兩個(gè)參數(shù)相同。
譯者注:原文寫(xiě)的是左移,根據(jù)上下文,應(yīng)為右移,暫且視為作者筆誤,下文減法步驟中同。
譯者注:原文寫(xiě)的是「D」,但表中用的是「?α」,遂糾正,下同。我猜作者在輸了一遍「?α」之后覺(jué)得麻煩,打算完稿之后統(tǒng)一替換,結(jié)果忘了……全文有不少此類(lèi)不夠嚴(yán)謹(jǐn)?shù)募?xì)節(jié),大抵是由于沒(méi)有正式發(fā)表的緣故。
減法執(zhí)行如下步驟:
- 在指數(shù)單元中計(jì)算指數(shù)的之差?α,
- 選擇較大的指數(shù),
- 將較小的數(shù)的尾數(shù)右移?α位,
- 尾數(shù)相減,
- 將結(jié)果規(guī)格化,
- 結(jié)果的符號(hào)與絕對(duì)值較大的參數(shù)相同。
符號(hào)單元預(yù)先算得了符號(hào),最終結(jié)果的符號(hào)需要與它結(jié)合得出。
乘法
對(duì)于乘法,首先在Ph0,兩數(shù)的指數(shù)相加(準(zhǔn)則21,指數(shù)部分)。而后耗時(shí)17個(gè)Ph,從Bf中二進(jìn)制尾數(shù)的最低位檢查到最高位(從-16到0)。每一步,寄存器Bf都右移一位。比特位mm記錄著之前從-16的位置被移出來(lái)的那一位。如果移出來(lái)的是1,把Bg加到(之前剛右移了一位的)中間結(jié)果上,否則就把0加上去。這一算法如此計(jì)算結(jié)果:
Be = Bf0×20×Bg + Bf-1×2-1×Bg + ··· + Bf-16×2-16×Bg
做完乘法之后,如果尾數(shù)大于等于2,就在Ph18中將結(jié)果右移一位,使其規(guī)格化。Ph19負(fù)責(zé)將最終結(jié)果寫(xiě)到數(shù)據(jù)總線(xiàn)上。

除法
除法基于所謂的「不恢復(fù)余數(shù)法」,耗時(shí)21個(gè)Ph。從最高位到最低位,逐位算得商的各個(gè)比特。首先,在Ph0計(jì)算指數(shù)之差,而后計(jì)算尾數(shù)的除法。除數(shù)的尾數(shù)存放在寄存器Bg里,被除數(shù)的尾數(shù)存放在Bf。Ph0期間,將余數(shù)初始化至Bf。而后的每個(gè)Ph里,在余數(shù)上減去除數(shù)。若結(jié)果為正,置結(jié)果尾數(shù)的相應(yīng)位為1。若結(jié)果為負(fù),置結(jié)果尾數(shù)的相應(yīng)位為0。如此逐位計(jì)算結(jié)果的各個(gè)位,從位0到位-16。Z1中有一種機(jī)制,可以按需對(duì)寄存器Bf進(jìn)行逐位設(shè)置。
如果余數(shù)為負(fù),有兩種對(duì)付策略。在「恢復(fù)余數(shù)法」中,把除數(shù)D加回到余數(shù)(R-D)上,從而重新得到正的余數(shù)R。而后余數(shù)左移一位(相當(dāng)于除數(shù)右移一位),算法繼續(xù)。在「不恢復(fù)余數(shù)法」中,余數(shù)R-D左移一位,加上除數(shù)D。由于前一步中的R-D是負(fù)的,左移使他擴(kuò)大到2R-2D。此時(shí)加上除數(shù),得2R-D,相當(dāng)于R左移之后與D的差,算法得以繼續(xù)。重復(fù)這一步驟直至余數(shù)為正,之后我們就又可以減去除數(shù)D了。在下表中,u+2表示二進(jìn)制冪中,位置2那兒的進(jìn)位。若此位為1,說(shuō)明加法的結(jié)果為負(fù)(2的補(bǔ)數(shù)算法)。
不恢復(fù)余數(shù)法是一種計(jì)算兩個(gè)浮點(diǎn)型尾數(shù)之商的優(yōu)雅算法,它省去了存儲(chǔ)的步驟(一個(gè)加法Ph的時(shí)耗)。

譯者注:原文寫(xiě)的是除數(shù)在Bf、被除數(shù)在Bg,又是一處明顯的筆誤。
奇怪的是,Z3在做除法時(shí),會(huì)先測(cè)試Ba和Bb之差是否可能為負(fù),若為負(fù),就走Ba到Be的一條捷徑總線(xiàn)使減去的除數(shù)無(wú)效(丟棄這一結(jié)果)。復(fù)制品沒(méi)有使用這一方法,不恢復(fù)余數(shù)法比它優(yōu)雅得多。
8 輸入和輸出
輸入控制臺(tái)由4列、每列10塊小盤(pán)構(gòu)成。操作員可以在每一列(從左至右分別為Za3、Za2、Za1、Za0)上撥出數(shù)字0~9。意即,能輸入任意的四位十進(jìn)制數(shù)。每撥一位數(shù),便相應(yīng)生成等效的、4比特長(zhǎng)的二進(jìn)制值。因而,該輸入控制臺(tái)相當(dāng)于一張4×10的表,存著10個(gè)0~9的二進(jìn)制值。
而后Z1的處理器負(fù)責(zé)將各十進(jìn)制位Za3、Za2、Za1、Za0通過(guò)寄存器Ba(在Ba-13的位置,對(duì)應(yīng)冪2-13)傳到數(shù)據(jù)通路上。先輸入Za3(到寄存器Ba),乘以10。再輸入Za2,再乘以10。四個(gè)位,皆如是重復(fù)。Ph7過(guò)后,4位十進(jìn)制數(shù)的二進(jìn)制等效值就在Be中誕生了。Ph8,如有需要,將尾數(shù)規(guī)格化。Ph7將常數(shù)13(二進(jìn)制是LL0L)加到指數(shù)上,以確保在尾數(shù)-13的位置上輸入數(shù)。
用一根小桿設(shè)置十進(jìn)制的指數(shù)。Ph9中,這根小桿所處的位置代表了輸入時(shí)要乘多少次10。

圖19中的表展示了如何將寄存器Bf中的二進(jìn)制數(shù)轉(zhuǎn)換成在輸出面板上顯示的十進(jìn)制數(shù)。
為免遇到要處理負(fù)十進(jìn)制指數(shù)的情況,先給寄存器Bf中的數(shù)乘上10-6(祖思限制了機(jī)器只能操作大于10-6的結(jié)果,即便ALU中的中間結(jié)果可以更小些)。這在Ph1完成。這一乘法由Z1的乘法運(yùn)算完成,整個(gè)過(guò)程中,二-十進(jìn)制譯者注轉(zhuǎn)換保持「掛起」。
譯者注:原文寫(xiě)的十-二進(jìn)制,目測(cè)筆誤。

此后,尾數(shù)右移兩位(以使二進(jìn)制小數(shù)點(diǎn)的左邊有4個(gè)比特)。尾數(shù)持續(xù)位移,直到指數(shù)為正,乘3次10。每乘一次,把尾數(shù)的整數(shù)部分拷貝出來(lái)(4個(gè)比特),把它從尾數(shù)里刪去,并根據(jù)一張表(Ph4~7中的2Be'-8Be'操作)轉(zhuǎn)換成十進(jìn)制的形式。各個(gè)十進(jìn)制位(從最高位開(kāi)始)顯示到輸出面板上。每乘一次10,十進(jìn)制顯示中的指數(shù)箭頭就左移一格位置。譯者注
譯者注:說(shuō)實(shí)話(huà)這一段沒(méi)完全看懂,翻譯可能與原意有出入。
9 總結(jié)
Z1的原型機(jī)毀于1943年12月柏林一場(chǎng)盟軍的空襲中。如今已不可能判定Z1的復(fù)制品是否和原型一樣。從幸存的那些照片上看,原型機(jī)是個(gè)大塊頭,而且不那么「規(guī)則」。此處我們只能相信祖思本人所言。但我覺(jué)得,盡管他沒(méi)什么理由要在重建的過(guò)程中有意識(shí)地去「潤(rùn)色」Z1,記憶卻可能悄悄動(dòng)著手腳。祖思在1935~1938年間記下的那些筆記看起來(lái)與后來(lái)的復(fù)制品一致。據(jù)他所言,1941建成的Z3和Z1在設(shè)計(jì)上十分相似。
20世紀(jì)80年代,西門(mén)子(收購(gòu)了祖思的計(jì)算機(jī)公司)為重建Z1提供了資金。在兩名學(xué)生的輔助下,祖思在自己家中完成了所有的建造工作。建成之后,為方便起重機(jī)把機(jī)器吊起來(lái),運(yùn)送至柏林,結(jié)果祖思家樓上拆掉了一部分墻。
重建的Z1是臺(tái)優(yōu)雅的計(jì)算機(jī),由成千上萬(wàn)的部件組成,但并沒(méi)有多余。比如尾數(shù)ALU的輸出可以?xún)H由兩個(gè)移位器實(shí)現(xiàn),但祖思設(shè)置的那些移位器明顯以較低的代價(jià)提升了算術(shù)運(yùn)算的速率。我甚至發(fā)現(xiàn),Z1的處理器比Z3的更優(yōu)雅,它更簡(jiǎn)潔,更「原始」。祖思似乎是在采用了更簡(jiǎn)單、更可靠的電話(huà)繼電器之后,反而在CPU的尺寸上「鋪張浪費(fèi)」。同樣的事也發(fā)生在Z3若干年后的Z4身上。Z4根本就是大版的Z3,有著大版的指令集,而計(jì)算機(jī)架構(gòu)是基本一樣的,就算它的指令更多。機(jī)械式的Z1從未能一直正常運(yùn)行,祖思本人后來(lái)也稱(chēng)之為「一條死胡同」。他曾開(kāi)玩笑說(shuō),1989年Z1的復(fù)制品那是相當(dāng)精確,因?yàn)樵蜋C(jī)其實(shí)不可靠,雖然復(fù)制品也可靠不到哪去??缮衿娴氖?,Z4為了節(jié)省繼電器而使用的機(jī)械式內(nèi)存卻非??煽?。1950~1955年間,Z4在瑞士的蘇黎世聯(lián)邦理工學(xué)院(ETH Zürich)服役,其機(jī)械內(nèi)存運(yùn)行良好[7]。
最令我驚訝的是,康拉德·祖思是何等年輕,就對(duì)計(jì)算機(jī)引擎給出了如此優(yōu)雅的設(shè)計(jì)。在美國(guó),ENIAC或MARK I團(tuán)隊(duì)都是由經(jīng)驗(yàn)豐富的科學(xué)家和電子專(zhuān)家組成的,與此相反,祖思的工作孤立無(wú)援,他還沒(méi)有什么實(shí)際經(jīng)驗(yàn)。從架構(gòu)上看,我們今天的計(jì)算機(jī)進(jìn)與1938年的祖思機(jī)一致,反而與1945年的ENIAC不同。直到后來(lái)的EDVAC報(bào)告草案,以及馮·諾依曼和圖靈開(kāi)發(fā)的位串行機(jī)中,才引進(jìn)了更優(yōu)雅的體系結(jié)構(gòu)。約翰·馮·諾依曼(John von Neumann)1926~1929年間居于柏林,是柏林大學(xué)最年輕的講師(報(bào)酬直接來(lái)自學(xué)生學(xué)費(fèi)的無(wú)薪大學(xué)教師)。那些年,康拉德·祖思和馮·諾依曼許能在不經(jīng)意間相遇相知。在那瘋狂席卷、那黑夜籠罩德國(guó)之前,柏林本該有著許多的可能。

參考文獻(xiàn)
[1] Horst Materna, Die Geschichte der Henschel Flugzeug-Werke in Sch?nefeld bei Berlin 1933-1945, Verlag Rockstuhl, Bad Langensalza, 2010.
[2] Zuse, K., Der Computer – Mein Lebenswerk, Springer-Verlag, Berlin, 3rd Edition, 1993.
[3] Rojas, R., "Konrad Zuse's legacy: the architecture of the Z1 and Z3", Annals of the History of Computing, Vol. 19, N. 2, 1997, pp. 5–16.
[4] Ursula Schweier, Dietmar Saupe, "Funktions- und Konstruktionsprinzipien der programmgesteuerten mechanischen Rechenmaschine Z1", Arbeitspapiere der GMD 321, GMD, Sankt Augustin, August 1998.
[5] Rojas, R. (ed.), Die Rechenmaschinen von Konrad Zuse, Springer-Verlag, Berlin, 1998.
[5] Website: Architecture and Simulation of the Z1 Computer, http: http://zuse-z1.zib.de/, last access: July 21st, 2013.
[6] Konrad Zuse, "Rechenvorrichtung aus mechanischen Schaltglieder", Zuse Papers, GMD 019/003 (undated), http://zuse.zib.de/, last access July 21st, 2013.
[7] Bruderer, H.: Konrad Zuse und die Schweiz: Wer hat den Computer erfunden?, Oldenbourg Wissenschaftsverlag, Munich, 2012.
[8] Goldstine, H.: "The Electronic Numerical Integrator and Computer (ENIAC)", Annals of the History of Computing, Vol. 18 , N. 1, 1996, S. 10–16.