English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

guest
1 / ?
back to lessons

用絕對二進制編程

最早的編程師用絕對二進制編程:每條指令和每個位址都是原始二進制數字。一條指令可能看起來像 01100101 00001010 — 指令代碼和記憶體位址都用二進制表示。

義大利麵式代碼問題

當錯誤需要插入新的指令時,編程師面臨一個困境。直接插入意味著所有後續指令的位址都會移位一格 — 編程師必須更新整個程式中的每個位址引用。這是災難性的。

解決方案:用跳轉指令替換插入點前面的指令,跳轉到空白記憶體。在該空白位置:寫出被覆蓋的指令,加入新指令,然後跳轉回去。當更正中出現錯誤時,再用同樣的技巧,使用其他空白記憶體。

結果:程式的執行路徑跳到看似隨機的位置。Hamming 稱此為「義大利麵罐」。控制流路徑如果畫在紙上,看起來完全像糾纏的義大利麵。

逃脫路線

兩個立即改進:八進制記號(將二進制數字分組為 3 位)和十六進制(分組為 4 位,使用 A–F 表示大於 9 的數值)。這些減少了書寫錯誤,但沒有解決根本的位址問題。

符號程式集(例如 IBM 的 SAP — 符號程式集程式,以及 IBM 650 上的 SOAP — 符號最佳化程式集程式)允許編程師寫指令名稱(ADD、MOVE)和符號位址標籤,而不是二進制。組譯器在輸入時翻譯成二進制,自動管理位址分配。

SOAP 進行了額外的最佳化:它在旋轉鼓上排列指令,使下一條指令在前一條完成時恰好到達讀取頭 — 最少延遲編碼。SOAP 甚至編譯自己:程式 A 作為數據被處理以產生 B,B 在 A 上執行以測量自編譯改進了多少。

解析樹和語言層級

函式庫和可重定位代碼

Hamming 指出,可重用軟體(數學函式庫)的想法來得很早 — Babbage 就設想過。問題在於:絕對位址的函式庫要求每個子程序每次使用時都佔據相同的記憶體位置。當函式庫總數變得過大時,程式爭奪同一位址。

解決方案:可重定位代碼。組譯器生成的指令相對於基礎位址(相對位址)而非絕對位址引用記憶體。連結器在載入時解析最終位址。

von Neumann 未發表的報告(廣泛流傳)描述了必要的編程技巧。第一本已發表的編程書籍(Wilkes、Wheeler & Gill,EDSAC,1951)將這些技術編纂成冊。

解釋為什麼絕對位址的函式庫造成可擴展性問題,以及可重定位代碼如何解決它。絕對位址的哪個特定特性造成衝突,以及「可重定位」在技術上意味著什麼?

語言設計的分岔點

FORTRAN(1957,IBM)和 ALGOL(1958,國際委員會)代表了兩種設計哲學,產生了根本不同的結果。

FORTRAN

John Backus 領導了 IBM 的 FORTRAN(FORmula TRANslation)項目。設計目標:讓科學家和工程師容易使用這種語言。FORTRAN 接受對其使用者自然的數學記號:A = B + C * D 而不是 ADD B, C; STORE T; MULTIPLY T, D; STORE A

FORTRAN 存活了 60 多年。它在科學計算、流體動力學、氣候建模和計算物理中仍在活躍使用。Hamming 將這種持久性視為成功設計的證明。

ALGOL

ALGOL(ALGOrithmic Language)由邏輯學家和計算機科學家委員會設計,目標是數學嚴格性:一種邏輯清晰、形式上可定義的語言。Backus-Naur 形式 (BNF) 用於描述語法的記號是為了指定 ALGOL 而發明的。

ALGOL 在實踐中失敗了。儘管其邏輯優雅及對後續語言設計的巨大影響(Pascal、C 及幾乎所有現代語言都源自 ALGOL 的語法概念),ALGOL 本身從未得到廣泛部署。Hamming 的判決:邏輯設計,人類難用。

語言層級

Hamming 描述了一個自然層級,從機器代碼經過組譯、高階語言,直到「問題導向語言」,接近從業者對其問題領域的思考方式。每個層級都增加了人類可讀性,但代價是機器效率。

Hamming 的四個語言設計標準

Hamming 將 FORTRAN 和 ALGOL 的教訓提煉為成功編程語言的四個標準:

1. 容易學習 — 新手可以快速變得有生產力

2. 容易使用 — 日常任務需要最少的儀式

3. 容易除錯 — 錯誤產生有意義的、可定位的訊息

4. 容易使用子程序 — 重用和抽象不需要英勇的努力

他補充了一個結構性觀察:人類語言約有 60% 的冗餘;書面語言約 40%。低冗餘語言(如 APL)產生編程師認為優美的單行程式,初學者認為難懂 — 且單個字元改變含義時包含無法檢測的錯誤。

含義:為邏輯優雅而設計的語言是為錯誤的讀者最佳化。編程師是人類;人類需要冗餘來捕捉錯誤和傳達意圖。

將 Hamming 的四個標準應用到你熟悉的編程語言。為每個標準評分 1–5(5 = 優秀)。然後確定哪個標準若加強會最改進該語言 — 並解釋具體變更看起來如何。

心理學 vs 邏輯語言設計

Hamming 回到 FORTRAN/ALGOL 的對比,作為制度和人類動力學的教訓,而不只是語言設計。

FORTRAN 是心理學地設計的 — 為會使用它的人類設計,特別是在數學記號中思考的科學家。ALGOL 是邏輯地設計的 — 為形式正確性和理論優雅性。

Hamming 認識到的悖論:人類拒絕的邏輯正確語言失敗;人類採用的實用設計語言成功,即使它邏輯上更雜亂。

他以 APL 為極端案例:邏輯優雅,單行可表達,有自己的特殊字元集。編程師喜歡它。普通編程師發現它難以閱讀。單個字元改變會以沉默方式轉換程式的含義。APL 有一個小的忠誠社群和幾乎沒有主流使用。

人類冗餘論證:口語約有 60% 的冗餘(重複的語境、澄清詞、可預測的結構)。書面語言約 40%。這種冗餘用於錯誤檢測 — 人類不可靠,所以語言演進為含有足夠的重複資訊來捕捉和糾正錯誤。低冗餘語言移除了這個安全網。

編譯器層級

Hamming 描述了編譯器/直譯器的分層:一個程式可以讀入高階語言並將其翻譯為低階語言。堆疊這些層 — 每個翻譯一級。在頂部:領域專家(生物學、金融、物理)自然寫的領域特定語言。在底部:機器代碼。每個轉換是編譯器或直譯器。

預測語言存活

到 1993 年,Hamming 目睹了許多語言的成功和失敗。FORTRAN(1957)倖存。ALGOL(1958)失敗。COBOL(1959)在商業計算中存活了數十年。LISP(1958)在 AI 研究中倖存。PL/I(1964)試圖統一一切,但失敗了。

使用 Hamming 的心理學 vs 邏輯設計區別和他的四個標準,解釋為什麼你知道的一種語言繁榮而另一種失敗(或正在失敗)。你的解釋應該確定推動採用或拒絕的具體人類因素 — 而不只是技術性質。

循環模式

Hamming 的軟體史章節包含一個循環結構:

1. 存在痛苦的限制(絕對位址、二進制記號、難以維護的代碼)

2. 有人發明抽象層來隱藏限制

3. 抽象層啟用新的規模,造成新的痛苦限制

4. 重複

二進制 → 八進制/十六進制 → 符號程式集 → FORTRAN → 結構化編程 → 物件導向語言 → 領域特定語言。每層解決前任的最急性痛點,同時引入新類別的問題。

義大利麵式代碼問題(絕對位址)導致符號程式集。大型組譯程式導致 FORTRAN。大型 FORTRAN 程式導致結構化編程,然後物件導向。Hamming 的演講在這些後來的轉換之前結束,但模式繼續。

他對工程師的教訓:你總是在解決前一個抽象層暴露的痛點。理解你目前所在的層級需要知道為什麼下面的層級存在。

認出你定期使用的軟體抽象層。它隱藏下面層級的什麼痛苦限制?而且你目前的層級引入什麼新類別的問題 — 上面的層級將需要解決什麼痛點?