簡單介紹一下編程方法的歷史演變。
——埃里克·奧(作者)
在計(jì)算的早期,硬件很昂貴,而程序員很便宜。 廉價(jià)的程序員甚至沒有“程序員”的頭??銜,通常由物理學(xué)家或電氣工程師擔(dān)任這個(gè)角色。 早期的計(jì)算機(jī)被用來快速解決復(fù)雜的物理問題,因此物理學(xué)家天然適合“編程”工作。
有哪些手續(xù)?
首先,介紹一下背景。 計(jì)算機(jī)本身不能做任何事情,它的任何行為都需要程序的指導(dǎo)。 您可以將程序視為非常精確的配方,它接受輸入并產(chǎn)生相應(yīng)的輸出。 配方中的每個(gè)步驟都包含用于操作數(shù)據(jù)的指令。 聽起來很復(fù)雜,但你似乎知道下面這句話的意思:
1 + 2 = 3
其中減號(hào)是“指令”,數(shù)字1和2是數(shù)據(jù)。 等號(hào)物理上意味著等式兩邊的部分是“等價(jià)的”,但在大多數(shù)編程語言中對變量使用等號(hào)意味著“賦值”。 如果計(jì)算機(jī)執(zhí)行了前面的句子,它會(huì)將減法的結(jié)果(即“3”)存儲(chǔ)在顯存中的某處。
計(jì)算機(jī)知道如何用數(shù)字進(jìn)行物理計(jì)算,以及如何連接內(nèi)存結(jié)構(gòu)中的數(shù)據(jù)。 顯存這里就不展開了,只需知道顯存一般分為“速度快/空間小”和“速度慢/空間大”兩類。 CPU寄存器的讀寫速度很快,而且占用的空間很小,相當(dāng)于一張速記紙條。 可尋址存儲(chǔ)器一般空間較大,讀寫速度比寄存器差很多。 程序運(yùn)行時(shí),CPU不斷地將其需要的數(shù)據(jù)從可尋址存儲(chǔ)器移至寄存器,然后將結(jié)果放回可尋址存儲(chǔ)器。
匯編器
當(dāng)時(shí)計(jì)算機(jī)價(jià)格昂貴,而人力相對便宜。 程序員需要花費(fèi)大量時(shí)間將手寫的物理表達(dá)式翻譯成計(jì)算機(jī)可以執(zhí)行的指令。 第一批計(jì)算機(jī)的用戶界面很糟糕,有些前面板上有翻轉(zhuǎn)開關(guān)。 這種開關(guān)代表視頻存儲(chǔ)器“單元”中的“0”和“1”。 程序員需要配置一個(gè)顯存單元物理英文翻譯器,選擇一個(gè)存儲(chǔ)位置,然后將該單元提交到顯存。 這是一個(gè)耗時(shí)且容易出錯(cuò)的過程。
程序員 (左)和 Fran Bilas(右)正在運(yùn)行
后來,一位電氣工程師覺得自己的時(shí)間很寶貴,于是寫了一個(gè)程序,將人們能理解的類似“菜譜”的輸入轉(zhuǎn)換成計(jì)算機(jī)能理解的版本。 這就是最初的“匯編器”,在當(dāng)時(shí)引起了不小的爭議。 如此昂貴的機(jī)器的所有者不想將計(jì)算資源浪費(fèi)在人類已經(jīng)可以完成的任務(wù)上(盡管速度慢且容易出錯(cuò))。 然而,隨著時(shí)間的推移,人們逐漸發(fā)現(xiàn)使用匯編程序在速度和準(zhǔn)確性方面比手動(dòng)編譯機(jī)器語言要好,但計(jì)算機(jī)所做的“真正的工作量”卻增加了。
雖然匯編器距離切換機(jī)器面板上的位狀態(tài)還有很長的路要走,但這些編程方法仍然非常專業(yè)。 里面的乘法實(shí)例在匯編語言中看起來像這樣:
01 MOV R0, 1 02 MOV R1, 2 03 ADD R0, R1, R2 04 MOV 64, R0 05 STO R2, R0
每一行都是一條計(jì)算機(jī)指令,后面是該指令的縮寫,旁邊是該指令所操作的數(shù)據(jù)。 這個(gè)小程序首先將值 1“移動(dòng)”到寄存器 R0,然后將 2 連接到寄存器 R1。 第03行將兩個(gè)寄存器R0和R1中的值相乘,并將結(jié)果存儲(chǔ)在寄存器R2中。 最后,第 04 行和第 05 行確定結(jié)果應(yīng)放置在尋址存儲(chǔ)器中的位置(本例中為地址 64)。 管理數(shù)據(jù)在視頻內(nèi)存中的存儲(chǔ)位置是編程過程中最耗時(shí)且最容易出錯(cuò)的部分之一。
翻譯員
匯編器已經(jīng)比手寫的計(jì)算機(jī)指令好得多了,但早期的程序員仍然希望能夠像他們習(xí)慣的方式編寫中文公式一樣編寫程序。 這些需求導(dǎo)致了中間編譯語言的發(fā)展,其中一些早已不復(fù)存在,而另一些至今仍在使用。 例如ALGO早已不復(fù)存在,而像C和C這樣的語言繼續(xù)解決實(shí)際問題。
ALGO 和編程語言的譜系樹
這種“高級(jí)”語言允許程序員以更簡單的形式編寫程序。 在 C 語言中,我們的乘法程序如下所示:
int x; x = 1 + 2;
第一句話描述了程序?qū)⑹褂玫囊曨l內(nèi)存塊。 在這個(gè)反例中,這個(gè)顯存應(yīng)該占據(jù)一個(gè)整數(shù)的大小,名稱為x。 第二句話是乘法,盡管寫反了。 AC 程序員會(huì)說這是“X 被參數(shù)化為 1 加 2 的結(jié)果”。 需要注意的是,程序員不需要決定將x存儲(chǔ)在顯存中的何處,這個(gè)任務(wù)留給編譯器。
這些新程序稱為“編譯器”,可以將用中間語言編寫的程序轉(zhuǎn)換為匯編語言物理英文翻譯器,然后使用匯編器將匯編語言轉(zhuǎn)換為機(jī)器可讀的程序。 這些程序組合通常稱為“工具鏈”,因?yàn)橐粋€(gè)程序的輸出成為另一程序的輸入。
當(dāng)從一臺(tái)計(jì)算機(jī)遷移到另一臺(tái)不同型號(hào)或品牌的計(jì)算機(jī)時(shí),編譯語言相對于匯編語言的優(yōu)勢是顯而易見的。 在計(jì)算的早期,IBM、DEC、德州儀器和惠普等公司制造了大量不同類型的計(jì)算機(jī)硬件。 這些計(jì)算機(jī)不僅都需要連接電源,而且沒有太多共同點(diǎn)。 它們在顯存和CPU架構(gòu)上有很大不同。 當(dāng)時(shí),人們往往需要幾年的時(shí)間才能將一臺(tái)計(jì)算機(jī)的程序翻譯成另一臺(tái)計(jì)算機(jī)的程序。
使用中間語言,我們只需要將編譯器工具鏈遷移到新平臺(tái)即可。 只要有編譯器可用,用中間語言編寫的程序就可以在新計(jì)算機(jī)上重新編譯,最多只進(jìn)行微小的更改。 中間語言的編寫是一項(xiàng)真正的革命性成就。
1983 年發(fā)布的 IBM PCXT 是硬件價(jià)格上漲的早期例子。
程序員的生活得到了很大的改善。 相比之下,通過中級(jí)語言表達(dá)他們想要解決的問題會(huì)讓事情變得容易很多。 由于半導(dǎo)體技術(shù)的進(jìn)步和集成芯片的發(fā)明,計(jì)算機(jī)硬件的價(jià)格大幅上漲。 計(jì)算機(jī)變得越來越快、越來越強(qiáng)大,而且價(jià)格也越來越便宜。 從某個(gè)時(shí)間點(diǎn)開始(實(shí)際上是 80 年代末),事情發(fā)生了逆轉(zhuǎn),程序員的價(jià)值超過了他們使用的硬件。
類庫
隨著時(shí)間的推移,一種新的編程方法盛行起來。 一種稱為“解釋器”的特殊程序可以直接讀取程序并將其轉(zhuǎn)換為計(jì)算機(jī)指令以立即執(zhí)行。 與編譯器非常相似,協(xié)程讀取程序并將其轉(zhuǎn)換為中間形式。 但與編譯器不同的是,協(xié)程直接執(zhí)行程序的這種中間形式。 解釋型語言每次執(zhí)行都要經(jīng)歷這個(gè)過程; 一個(gè)編譯好的程序只需要編譯一次,然后計(jì)算機(jī)每次只需要執(zhí)行編譯好的機(jī)器指令。
順便說一下,這個(gè)特性是人們認(rèn)為解釋程序運(yùn)行速度較慢的原因。 但現(xiàn)代計(jì)算機(jī)的功能如此強(qiáng)大,以至于大多數(shù)人很難區(qū)分編譯程序和解釋程序之間的區(qū)別。
解釋型程序(有時(shí)稱為“腳本”)更容易移植到不同的硬件平臺(tái)。 由于該腳本不包含任何特定于機(jī)器的指令,因此同一版本的程序可以在許多不同的計(jì)算機(jī)上運(yùn)行而無需任何更改。 但實(shí)際上,協(xié)程必須先移植到新機(jī)器上。
Perl 是一種非常流行的解釋語言。 Perl 中乘法問題的完整表述如下:
$x = 1 + 2
雖然這個(gè)程序看上去和C語言版本差不多,操作上也沒有太大區(qū)別,但是缺少初始化變量的語句。 盡管還存在一些其他差異(超出了本文的范圍),但您應(yīng)該已經(jīng)注意到,我們編寫計(jì)算機(jī)程序的方式已經(jīng)非常接近物理學(xué)家用筆和紙手寫物理表達(dá)式的方式。
虛擬機(jī)
最新的編程方法是虛擬機(jī)(通常縮寫為VM)。 虛擬機(jī)分為兩類:系統(tǒng)虛擬機(jī)和進(jìn)程虛擬機(jī)。 兩種類型的虛擬機(jī)都提供“真實(shí)”計(jì)算硬件的不同級(jí)別的表示,但它們具有不同的范圍。 系統(tǒng)虛擬機(jī)是一種軟件,可替代化學(xué)硬件,而進(jìn)程虛擬機(jī)則設(shè)計(jì)為以“系統(tǒng)獨(dú)立”方式執(zhí)行程序。 所以在這種情況下,進(jìn)程虛擬機(jī)(我之前提到的虛擬機(jī)就是指這種類型)的作用域和類庫類似,因?yàn)槌绦蛳缺痪幾g成中間形式,然后虛擬機(jī)執(zhí)行這種中間形式。
虛擬機(jī)和類庫的主要區(qū)別在于虛擬機(jī)創(chuàng)建一個(gè)虛擬CPU和一組虛擬指令。 有了這層表示,我們就可以通過編譯后端工具將不同語言的程序編譯成虛擬機(jī)可以接受的程序。 似乎最流行和最知名的虛擬機(jī)是Java虛擬機(jī)(JVM)。 JVM在20世紀(jì)90年代最初只支持Java語言,但現(xiàn)在它可以運(yùn)行許多流行的編程語言,包括Scala、JRuby、等等。 還有其他不太常見的情況,這里不再贅述。 我也是最近才知道,我最喜歡的語言不是解釋型語言,而是運(yùn)行在虛擬機(jī)上的語言!
虛擬機(jī)一直延續(xù)著允許程序員使用特定領(lǐng)域的編程語言來解決問題的歷史趨勢,對特定計(jì)算平臺(tái)的了解越來越少。
就是這樣
希望您喜歡這篇簡短的文章,它簡要解釋了該軟件在幕后的工作原理。 您還希望我了解其他主題嗎? 請?jiān)谠u(píng)論中告訴我。
通過:
作者:ErikO' 題目:譯者:chen-ni 校對:wxy
本文由 LCTT 原創(chuàng)編譯,Linux China Honor 首發(fā)