日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

Part 1. 機(jī)器指令

機(jī)器指令到匯編再到高級(jí)編程語言

 

上一次 我們已經(jīng)了解了 二進(jìn)制和 CPU 的基本原理,知道了程序運(yùn)行時(shí),CPU 每秒數(shù)以億次、十億次、百億次地震蕩著時(shí)鐘,同步執(zhí)行著微小的 「電子操作」,例如:從內(nèi)存讀取一個(gè)字節(jié)的數(shù)據(jù)到 CPU 又或者判斷字節(jié)中的某一位是 0 還是 1。

CPU 本身有一組 規(guī)定好的 可以執(zhí)行的 「基本動(dòng)作」(被稱為 機(jī)器指令):

  1. 讀取指令;2. 執(zhí)行指令;3. 寫寄存器;

這幾乎就是 CPU 工作的全部了。 這些動(dòng)作雖然每次只能執(zhí)行一次,但是每秒可以執(zhí)行數(shù)十億次,這個(gè)數(shù)量級(jí)的「小操作」累加成為一個(gè)大的「有用的操作」。

處理器所做的一切都是基于這些微小的操作!幸運(yùn)的是,我們已經(jīng)不再需要了解這些操作的詳細(xì)信息就可以編寫和使用各類程序。諸如 JAVA 這一類的 「高級(jí)語言」 的 目的就是 將這些微小的電子操作組織成由人類可讀的「程序語言」表示的大型有用單元

機(jī)器指令演示

一條 機(jī)器指令 一般由內(nèi)存中的幾個(gè)字節(jié)組成,它們告訴 CPU 應(yīng)該執(zhí)行一個(gè)什么樣的「機(jī)器操作」(是取數(shù)據(jù)還是寫寄存器等..)。處理器依次查看 CPU 中的機(jī)器指令,并執(zhí)行每一條。內(nèi)存中的一組機(jī)器指令被稱為 「機(jī)器語言程序」,或稱為 「可執(zhí)行程序」

下面我們來使用機(jī)器語言來演示一個(gè)控制燈泡亮度的機(jī)器語言程序。

先和硬件做好規(guī)定

假設(shè)燈泡由內(nèi)存中的某一個(gè)程序控制,該程序能夠完全打開和關(guān)閉燈泡,可以使燈泡變亮或變暗,機(jī)器指令一個(gè)字節(jié)長(zhǎng)度,并且與機(jī)器操作對(duì)應(yīng)如下:

機(jī)器指令機(jī)器操作00000000停止程序00000001完全打開燈泡00000010完全關(guān)閉燈泡00000100燈泡暗淡 10%00001000將燈泡照亮 10%00010000如果燈泡完全點(diǎn)亮,則跳過下一條說明00100000如果燈泡完全熄滅,請(qǐng)?zhí)^下一條說明01000000轉(zhuǎn)到程序的開始(地址 0)

Demo 程序 && 演示

根據(jù)上方作出的規(guī)定,我們寫下如下的程序:(為了方便理解,我把對(duì)應(yīng)的機(jī)器操作也寫在了后面,實(shí)際的程序只包含機(jī)器指令)

地址機(jī)器指令機(jī)器操作000000001完全打開燈泡100000010完全關(guān)閉燈泡200000001完全打開燈泡300000100燈泡暗淡10%400000100燈泡暗淡10%500000000停止程序

所以這樣的一段程序執(zhí)行效果就如下圖:

機(jī)器指令到匯編再到高級(jí)編程語言

 

您可以嘗試自己利用 01000000(跳轉(zhuǎn)到程序開始) 來改寫程序來達(dá)到讓「燈逐漸變亮又逐漸變暗」的目的。

小結(jié)

上面演示的程序 核心思想 是:

  • 機(jī)器語言程序是內(nèi)存中一系列機(jī)器指令的集合;
  • 機(jī)器指令由一個(gè)或多個(gè)字節(jié)組成(在此示例中,僅一個(gè)字節(jié));
  • 處理器一次運(yùn)行一條機(jī)器指令的程序;
  • 所有的小機(jī)器操作加起來都是有用的;

在實(shí)際的 CPU 中,擁有更多的機(jī)器指令,而且更詳細(xì),并且不同的 CPU,指令集是不同的。典型的 CPU 擁有一千或更多的機(jī)器指令。

Part 2. 匯編語言

機(jī)器指令到匯編再到高級(jí)編程語言

 

  • 圖片來源:http://www.ruanyifeng.com/blog/2018/01/assembly-language-primer.html

機(jī)器語言太 "反人類”

我們已經(jīng)可以開始寫一些程序使用了,但是使用 機(jī)器語言編寫代碼會(huì)十分辛苦,比如:

00000001 00000010 00000001
00000100 00000100 00000000

即使你剛看過你也會(huì)對(duì)這一段就在 上方的實(shí)例代碼 沒有什么感知,這是因?yàn)闄C(jī)器語言是設(shè)計(jì)給機(jī)器的,人類記憶和使用起來就會(huì)顯得十分麻煩。

如此你就會(huì)感知到 上個(gè)世紀(jì) 的程序員使用 打孔卡片

機(jī)器指令到匯編再到高級(jí)編程語言

 

使用 紙帶

機(jī)器指令到匯編再到高級(jí)編程語言

 

甚至是 直接插拔線路 or 按下開關(guān)

機(jī)器指令到匯編再到高級(jí)編程語言

 

是一件多么硬核的事情...

機(jī)器指令到匯編再到高級(jí)編程語言

 

如果你對(duì)它們?nèi)绾喂ぷ饕约岸嗝从埠烁信d趣,可以參考一下下方的鏈接:

開發(fā)語言小傳之一:最早的編程語言——機(jī)器語言 - https://blog.csdn.NET/killer080414/article/details/42219091

50年前的登月程序和程序員有多硬核 - https://coolshell.cn/articles/19612.html、

再附帶一個(gè)寶藏網(wǎng)站(哥倫比亞大學(xué)出版的計(jì)算機(jī)歷史,非常詳細(xì)),有條件的同學(xué) 非常推薦 進(jìn)去瀏覽一下:

http://www.columbia.edu/cu/computinghistory/index.html

匯編語言誕生

CPU 的指令都是 二進(jìn)制 的,這顯然對(duì)于人類來說是 不可讀 的。為了解決二進(jìn)制指令的可讀性問題,工程師將那些指令寫成了 八進(jìn)制。二進(jìn)制轉(zhuǎn)八進(jìn)制是輕而易舉的,但是八進(jìn)制的可讀性也不行。

很自然地,最后還是用文字表達(dá),加法指令寫成 ADD。內(nèi)存地址也不再直接引用,而是用標(biāo)簽 表示。

這樣的話,就多出一個(gè)步驟,要把這些文字指令翻譯成二進(jìn)制,這個(gè)步驟就稱為 assembling,完成這個(gè)步驟的程序就叫做 assembler。它處理的文本,自然就叫做 aseembly code。標(biāo)準(zhǔn)化以后,稱為 assembly language,縮寫為 asm,中文譯為 匯編語言

機(jī)器指令到匯編再到高級(jí)編程語言

 

  • 圖片來源:http://www.ruanyifeng.com/blog/2018/01/assembly-language-primer.html

理解匯編語言

每一種 CPU 的機(jī)器指令都是不一樣的,因此對(duì)應(yīng)的匯編語言也不一樣。本文介紹的是目前最常見的 x86 匯編語言,即 Intel 公司的 CPU 使用的那一種。

寄存器

要學(xué)習(xí)匯編語言,首先必須了解兩個(gè)知識(shí)點(diǎn):寄存器 和 內(nèi)存模型

先來看寄存器。CPU 本身只負(fù)責(zé)運(yùn)算,不負(fù)責(zé)儲(chǔ)存數(shù)據(jù)。數(shù)據(jù)一般都儲(chǔ)存在內(nèi)存之中,CPU 要用的時(shí)候就去內(nèi)存讀寫數(shù)據(jù)。但是,CPU 的運(yùn)算速度遠(yuǎn)高于內(nèi)存的讀寫速度,為了避免被拖慢,CPU 都自帶一級(jí)緩存和二級(jí)緩存。基本上,CPU 緩存可以看作是讀寫速度較快的內(nèi)存。

但是,CPU 緩存還是不夠快,另外數(shù)據(jù)在緩存里面的地址是不固定的,CPU 每次讀寫都要尋址也會(huì)拖慢速度。因此,除了緩存之外,CPU 還自帶了寄存器(register),用來儲(chǔ)存最常用的數(shù)據(jù)。也就是說,那些最頻繁讀寫的數(shù)據(jù)(比如循環(huán)變量),都會(huì)放在寄存器里面,CPU 優(yōu)先讀寫寄存器,再由寄存器跟內(nèi)存交換數(shù)據(jù)。

機(jī)器指令到匯編再到高級(jí)編程語言

 

寄存器不依靠地址區(qū)分?jǐn)?shù)據(jù),而依靠名稱。每一個(gè)寄存器都有自己的名稱,我們告訴 CPU 去具體的哪一個(gè)寄存器拿數(shù)據(jù),這樣的速度是最快的。有人比喻寄存器是 CPU 的零級(jí)緩存。

寄存器的種類

早期的 x86 CPU 只有 8 個(gè)寄存器,而且每個(gè)都有不同的用途。現(xiàn)在的寄存器已經(jīng)有100 多個(gè)了,都變成通用寄存器,不特別指定用途了,但是早期寄存器的名字都被保存了下來。

“EAXEBXECXEDXEDIESIEBPESP

上面這 8 個(gè)寄存器之中,前面七個(gè)都是通用的。ESP 寄存器有特定用途,保存當(dāng)前 Stack 的地址(詳見下一節(jié))。

機(jī)器指令到匯編再到高級(jí)編程語言

 

我們常常看到 32 位 CPU、64 位 CPU 這樣的名稱,其實(shí)指的就是寄存器的大小。32 位 CPU 的寄存器大小就是 4 個(gè)字節(jié)。

內(nèi)存模型:Heap(堆)

寄存器只能存放很少量的數(shù)據(jù),大多數(shù)時(shí)候,CPU 要指揮寄存器,直接跟內(nèi)存交換數(shù)據(jù)。所以,除了寄存器,還必須了解內(nèi)存怎么儲(chǔ)存數(shù)據(jù)。

程序運(yùn)行的時(shí)候,操作系統(tǒng)會(huì)給它分配一段內(nèi)存,用來儲(chǔ)存程序和運(yùn)行產(chǎn)生的數(shù)據(jù)。這段內(nèi)存有起始地址和結(jié)束地址,比如從 0x1000 到 0x8000,起始地址是較小的那個(gè)地址,結(jié)束地址是較大的那個(gè)地址。

機(jī)器指令到匯編再到高級(jí)編程語言

 

程序運(yùn)行過程中,對(duì)于動(dòng)態(tài)的內(nèi)存占用請(qǐng)求(比如新建對(duì)象,或者使用 malloc 命令),系統(tǒng)就會(huì)從預(yù)先分配好的那段內(nèi)存之中,劃出一部分給用戶,具體規(guī)則是從起始地址開始劃分(實(shí)際上,起始地址會(huì)有一段靜態(tài)數(shù)據(jù),這里忽略)。舉例來說,用戶要求得到 10 個(gè)字節(jié)內(nèi)存,那么從起始地址 0x1000 開始給他分配,一直分配到地址 0x100A,如果再要求得到 22 個(gè)字節(jié),那么就分配到 0x1020。

機(jī)器指令到匯編再到高級(jí)編程語言

 

這種因?yàn)橛脩糁鲃?dòng)請(qǐng)求而劃分出來的內(nèi)存區(qū)域,叫做 Heap(堆)。它由起始地址開始,從低位(地址)向高位(地址)增長(zhǎng)。Heap 的一個(gè)重要特點(diǎn)就是不會(huì)自動(dòng)消失,必須手動(dòng)釋放,或者由垃圾回收機(jī)制來回收。

內(nèi)存模型:Stack(棧)

除了 Heap 以外,其他的內(nèi)存占用叫做 Stack(棧)。簡(jiǎn)單說,Stack 是由于 函數(shù)運(yùn)行而 臨時(shí)占用 的內(nèi)存區(qū)域。

機(jī)器指令到匯編再到高級(jí)編程語言

 

例如我們?cè)趫?zhí)行一個(gè)叫 main 的函數(shù)時(shí),會(huì)為它在內(nèi)存里面創(chuàng)建一個(gè) ,用來保存所有main 中使用的內(nèi)部變量。main 函數(shù)執(zhí)行結(jié)束后,該幀就會(huì)被回收,釋放所有的內(nèi)部變量,不再占用空間。

機(jī)器指令到匯編再到高級(jí)編程語言

 

如果在 main 函數(shù) 內(nèi)部調(diào)用了其他函數(shù),例如 add_a_and_b 函數(shù),那么執(zhí)行到這一行的時(shí)候,系統(tǒng)也會(huì)為 add_a_and_b 新建一個(gè)幀,用來儲(chǔ)存它的內(nèi)部變量。也就是說,此時(shí)同時(shí)存在兩個(gè)幀:main 和 add_a_and_b。一般來說,調(diào)用棧有多少層,就有多少幀。

機(jī)器指令到匯編再到高級(jí)編程語言

 

等到 add_a_and_b 運(yùn)行結(jié)束,它的幀就會(huì)被回收,系統(tǒng)會(huì)回到函數(shù) main 剛才中斷執(zhí)行的地方,繼續(xù)往下執(zhí)行。通過這種機(jī)制,就實(shí)現(xiàn)了函數(shù)的 層層調(diào)用,并且 每一層都能使用自己的本地變量

我們可以把棧理解為一個(gè)下方密封,而上方打開的「桶」。

機(jī)器指令到匯編再到高級(jí)編程語言

 

生成的新幀放入我們稱之為 「入棧」,而釋放幀我們稱之為 「出棧」棧的特點(diǎn) 就是,最晚入棧的幀最早出棧(因?yàn)樽顑?nèi)層的函數(shù)調(diào)用,最先結(jié)束運(yùn)行),這就叫做 "后進(jìn)先出" 的數(shù)據(jù)結(jié)構(gòu)。每一次函數(shù)執(zhí)行結(jié)束,就自動(dòng)釋放一個(gè)幀,所有函數(shù)執(zhí)行結(jié)束,整個(gè)棧就都釋放了。

匯編語言演示

舉個(gè)簡(jiǎn)單的例子,我們需要計(jì)算:

(1 + 4) * 2 + 3

我們按照 「后綴表示法」 進(jìn)行一下轉(zhuǎn)換:

1,4,+,2,*,3,+

我們平常使用的方法是 「中綴表示法」,也就是把計(jì)算符號(hào)放中間,例如 1 + 3,后綴則是把符號(hào)放最后,例如 1, 3, +。

這樣做的好處是沒有先乘除后加減的影響,也沒有括號(hào),直接運(yùn)算就行了。(例如 1, 3, +,先把 1 和 3 保存起來碰到 + 知道是加法則直接相加)

OK,我們從頭開始使用匯編語言來編寫一下程序,首先第一步:把 1 保存起來(放入寄存器):

MOV  1

之后是 4, +,那就直接加一下:

ADD 4

然后是 2, *,那就直接乘一下(SHL 是向左移動(dòng)一位的意思,二進(jìn)制中左移一個(gè)單位就相當(dāng)于乘以 2,例如 01 表示 1,而 10 則表示 2):

SHL 0

最后是 3, +,再加一下:

ADD 3

完整程序如下:

MOV  1
ADD  4
SHL  0
ADD  3

這似乎看起來比 00001111 這樣的二進(jìn)制要好上太多了!程序員們感動(dòng)到落淚:

機(jī)器指令到匯編再到高級(jí)編程語言

 

Part 3. 高級(jí)編程語言

機(jī)器指令到匯編再到高級(jí)編程語言

 

擺脫了 二進(jìn)制,我們有了更可讀的 匯編語言,但仍然十分繁瑣和復(fù)雜,每一條匯編指令代表一個(gè)基本操作,例如:「從內(nèi)存 x 位置獲取一個(gè)數(shù)字并放入寄存器 A」、「將寄存器 A 中的數(shù)字添加到寄存器 B 的數(shù)字上」。這樣的編程風(fēng)格既費(fèi)時(shí)又容易出錯(cuò),并且一旦出錯(cuò)還很難發(fā)現(xiàn)。

例如,我們來看一看 「1969 年阿波羅 11號(hào)登月計(jì)劃」 用來 防止登月艙計(jì)算機(jī)耗盡自身資源 的 BAILOUT 代碼:

POODOO    INHINT
    CA  Q
    TS  ALMCADR
 
    TC  BANKCALL
    CADR  VAC5STOR  # STORE ERASABLES FOR DEBUGGING PURPOSES.
 
    INDEX  ALMCADR
    CAF  0
ABORT2    TC  BORTENT
 
OCT77770  OCT  77770    # DONT MOVE
    CA  V37FLBIT  # IS AVERAGE G ON
    MASK  FLAGWRD7
    CCS  A
    TC  WHIMPER -1  # YES.  DONT DO POODOO.  DO BAILOUT.
 
    TC  DOWNFLAG
    ADRES  STATEFLG
 
    TC  DOWNFLAG
    ADRES  REINTFLG
 
    TC  DOWNFLAG
    ADRES  NODOFLAG
 
    TC  BANKCALL
    CADR  MR.KLEAN
    TC  WHIMPER
  • 出處:改變世界的代碼行 - https://www.infoq.cn/article/5CaYH8NbS6BmptWKRgkX

似乎不太容易讀的樣子...

阿波羅登月計(jì)劃的源代碼在 Github 上已經(jīng)公開,有興趣的可以去下方鏈接膜拜一下(可以去感受一下當(dāng)時(shí)程序員的工程能力):

https://github.com/chrislgarry/Apollo-11

另外附一下當(dāng)時(shí)代碼的設(shè)計(jì)負(fù)責(zé)人 Margaret Heafield Hamilton(女程序員)和完成的堆起來跟人一樣高的代碼量:

第一個(gè)高級(jí)語言:FORTRAN

當(dāng) John Backus 在 1950 年以一名科學(xué)程序員的身份加入 IBM 時(shí),已經(jīng)可以使用諸如 ADD 之類的助記詞代替數(shù)字代碼來編寫程序,也就是我們的匯編語言。這使編程變得容易一些,但是即使是一個(gè)簡(jiǎn)單的程序也需要數(shù)十次操作,并且仍然很難找到錯(cuò)誤。

巴克斯認(rèn)為,應(yīng)該有可能創(chuàng)建一種編程語言,使一系列計(jì)算可以用類似于數(shù)學(xué)符號(hào)的形式來表達(dá)。然后,使用特定的翻譯程序(以今天的術(shù)語來說是編譯器)可以將其轉(zhuǎn)換為計(jì)算機(jī)可以理解的數(shù)字代碼。

Backus 在 1953 年向他的經(jīng)理提出了這個(gè)想法。他得到了預(yù)算,并被鼓勵(lì)雇用一個(gè)小團(tuán)隊(duì)來測(cè)試該想法的可行性。三年后,該團(tuán)隊(duì)發(fā)布了一本手冊(cè),其中描述了 IBM Mathematical Formula Translating System(簡(jiǎn)稱 FORTRAN)。不久之后, IBM 向 IBM 704 的用戶提供了第一個(gè) FORTRAN 編譯器。

機(jī)器指令到匯編再到高級(jí)編程語言

 

FORTRAN 之父

Backus 和他的團(tuán)隊(duì)創(chuàng)造了世界上第一種高級(jí)編程語言。科學(xué)家和工程師將不再需要將其程序編寫為數(shù)字代碼或冗長(zhǎng)的助記符

FORTRAN 代碼演示

下面演示計(jì)算并輸出 8 * 6 的代碼實(shí)例:

program VF0944
implicit none

integer a, b, c
a= 8
b= 6
c= a*b

print *, 'Hello World, a, b, c= ', a, b, c
end program VF0944

對(duì)比匯編代碼,是不是看上去要清晰(人類可讀)多了呢?

FORTRAN 的意義

FORTRAN 的問世在計(jì)算機(jī)史上具有劃時(shí)代的意義,它使計(jì)算機(jī)語言從原始的低級(jí)匯編語言走出來,進(jìn)入了更高的境界,使得 計(jì)算機(jī)語言不再是計(jì)算機(jī)專家的專利,使廣大的工程技術(shù)人員有了進(jìn)行計(jì)算機(jī)編程的手段。

由此計(jì)算機(jī)更快地深入到了社會(huì)之中,它在工業(yè)部門中初露頭角,更是在火箭、導(dǎo)彈、人造地球衛(wèi)星的設(shè)計(jì)中大顯身手,因此有人稱 FORTRAN 語言使計(jì)算機(jī)的工業(yè)應(yīng)用成了可能,是推動(dòng)第二次世界大戰(zhàn)以后西方工業(yè)經(jīng)濟(jì)復(fù)蘇和進(jìn)入第二次工業(yè)革命的無形力量,是 "看不見的蒸汽機(jī)"。

FORTRAN 后時(shí)代

FORTRAN 高級(jí)程序設(shè)計(jì)語言的出現(xiàn)孕育了計(jì)算機(jī)軟件業(yè),繼其之后,計(jì)算機(jī)高級(jí)程序語言的開發(fā)進(jìn)入到了一個(gè)蓬勃發(fā)展的時(shí)代。

1959

Grace Hopper 發(fā)明了第一個(gè)面向企業(yè)業(yè)務(wù)的編程語言,又稱 “面向商業(yè)的通用語言”,也常常簡(jiǎn)稱 COBOL。

1964

美國(guó)達(dá)特茅斯學(xué)院約翰·凱梅尼和托馬斯·卡茨認(rèn)為,像 FORTRAN 那樣的語言太過專業(yè),編程非常困難。于是他們簡(jiǎn)化了 FORTRAN,并設(shè)計(jì)出了更適合初學(xué)者的 BASIC 語言。

1970

尼古拉斯·沃斯非常癡迷于編程語言,他率先提出了結(jié)構(gòu)化程序設(shè)計(jì)思想并發(fā)明了 Pascal 語言。

此外他還提出了 Wirth 定律,意為 “軟件變慢的速度比硬件變快的速度更快”,這讓摩爾定律變得充滿諷刺。之后的 Electron.js 也確實(shí)證明了這一點(diǎn)。

1972

丹尼斯·里奇在貝爾實(shí)驗(yàn)室工作期間發(fā)明了 C 語言,開啟了現(xiàn)代程序語言的革命。之后,他又添加了段錯(cuò)誤和其他一些幫助開發(fā)人員的實(shí)用功能,大大提升了編程效率。

除了 C 語言之外, 他和貝爾實(shí)驗(yàn)室的同事還創(chuàng)造了偉大的 Unix 操作系統(tǒng)。

1980

Alan Kay 發(fā)明了面向?qū)ο蟮木幊陶Z言 Smalltalk,在 Smalltalk 中,一切皆對(duì)象。

1987

拉里·沃爾發(fā)明了 Perl 語言。

1983

Jean Ichbiah 發(fā)現(xiàn) Ada Lovelace 的程序從未運(yùn)行成功過,因此決定用她的名字創(chuàng)建一種語言,于是 Ada 語言誕生了。

1986

Brac Box 和 Tol Move 通過融合 C 語言和 Smalltalk 的特征,發(fā)明了 Objective-C。但由于其語法晦澀,不太容易理解。

1983

Bjarne Stroustrup 在 C 語言的基礎(chǔ)上引入并擴(kuò)充了面向?qū)ο蟮母拍睿l(fā)明了—種新的程序語言并將其命名為 C++。

C++ 大大提升了應(yīng)用程序的編程效率。

1991

Guido van Rossum 討厭帶有大括號(hào)的編程語言,于是他參考 Monty Python 和 Flying Circus 語法,并發(fā)明了 Python。

1993

Roberto Ierusalimschy 和其朋友創(chuàng)造了一門巴西本地的腳本語言。在本地化過程中,由于一個(gè)小的錯(cuò)誤使得索引從1開始,而不是0。這門語言就是 Lua。

1994

Rasmus Lerdorf 為他個(gè)人主頁的 CGI 腳本制作了一個(gè)模板引擎,用來統(tǒng)計(jì)他自己網(wǎng)站的訪問量。

這個(gè)文件被上傳到網(wǎng)上之后用它的人越來越多。后來又用 C 語言重新編寫,還添加了數(shù)據(jù)庫訪問功能。這門語言就是 php。

1995

松本行弘發(fā)明了 Ruby 語言。

1995

Brendan Eich 利用周末時(shí)間設(shè)計(jì)了一種語言,用于為世界各地的網(wǎng)頁瀏覽器提供支持,并最終推出了 Skynet。他最初去了 Netscape,并將這門語言命名為 LiveScript,后來在代碼審查期間 Java 逐漸開始風(fēng)靡,因此他們決定將其改名為 JavaScript。

后來 Java 使其陷入了商標(biāo)麻煩,于是 JavaScript 被更名為 ECMAScript。但是人們還是習(xí)慣稱之為 JavaScript。

1996

James Gosling 發(fā)明了 Java,這是 第一個(gè)真正意義上面向?qū)ο蟮镁幊陶Z言,其中設(shè)計(jì)模式在實(shí)用主義中占統(tǒng)治地位。

More...

對(duì)于這一段計(jì)算機(jī)歷史感興趣的同學(xué)可以拜讀一下「IT 通史 12.2 節(jié) - 高級(jí)計(jì)算機(jī)程序設(shè)計(jì)語言」的內(nèi)容,在線預(yù)覽鏈接如下:

https://books.google.com.hk/books?id=ZrAol3RzcNkC&printsec=frontcover&hl=zh-CN#v=onepage&q&f=false

高級(jí)語言分類

CPU 終究只認(rèn)識(shí)二進(jìn)制指令,在我們發(fā)明高級(jí)語言之后,仍然無可避免的需要進(jìn)行「翻譯」 工作。按照翻譯方式的不同,我們又把高級(jí)語言分為了 「編譯型」 和 「解釋型」

編譯型

機(jī)器指令到匯編再到高級(jí)編程語言

 

編譯型專業(yè)解釋為:

使用 專門的編譯器,針對(duì) 特定的平臺(tái),將高級(jí)語言源代碼 一次性 的編譯成可被該平臺(tái)硬件執(zhí)行的機(jī)器碼,并包裝成該平臺(tái)所能識(shí)別的可執(zhí)行性程序的格式,并且只需要編譯一次,以后再也不用編譯。其實(shí)可以簡(jiǎn)單理解成谷歌/ 百度翻譯,我們把要翻譯的文字全部放進(jìn)去,一次翻譯,下次使用直接使用上一次翻譯好的結(jié)果。

機(jī)器指令到匯編再到高級(jí)編程語言

 

  • 優(yōu)點(diǎn)(較解釋型):執(zhí)行效率高(有解釋器省去很多翻譯的過程)
  • 缺點(diǎn)(較解釋型):開發(fā)效率低(寫完所有的代碼才能檢查 bug,得多恐怖呀???)

解釋型

機(jī)器指令到匯編再到高級(jí)編程語言

 

解釋型專業(yè)解釋為:

使用 專門的解釋器 對(duì)源程序逐行解釋成 特定平臺(tái) 的機(jī)器碼并 立即執(zhí)行,它不需要事先編譯,直接將代碼解釋稱機(jī)器碼直接運(yùn)行,也就是說只要某一平臺(tái)提供了相應(yīng)的解釋器即可運(yùn)行代碼。其實(shí)可以理解成同聲傳譯,我們需要翻譯的時(shí)候,找一個(gè)翻譯員,對(duì)方說一句翻譯員翻譯一句,下次翻譯還是需要一個(gè)翻譯員一句一句的翻譯。

機(jī)器指令到匯編再到高級(jí)編程語言

 

  • 缺點(diǎn)(較編譯型):執(zhí)行效率低(寫一次翻譯一次)
  • 優(yōu)點(diǎn)(較編譯型):開發(fā)效率高(寫一行翻譯一行,錯(cuò)了馬上就知道,媽媽再也不用擔(dān)心我找不到 bug 了)

半解釋半編譯的 Java

不同廠商、不同時(shí)間開發(fā)的 CPU 的指令集是不一樣的,這就是上方為什么提到要使用專門的解釋器,要用于 特定的平臺(tái) 的原因。

所以 Java 為了實(shí)現(xiàn) 「一次編譯,到處運(yùn)行」 的目的,采用了一種特別的方案:先 編譯 為 與任何具體及其環(huán)境及操作系統(tǒng)環(huán)境無關(guān)的中間代碼(也就是 .class 字節(jié)碼文件),然后交由各個(gè)平臺(tái)特定的 Java 解釋器(也就是 JVM)來負(fù)責(zé) 解釋 運(yùn)行。

編程人員和計(jì)算機(jī)都無法直接讀懂字節(jié)碼文件,它必須由專用的 Java 解釋器來解釋執(zhí)行,因此 Java 是一種在 編譯基礎(chǔ)上進(jìn)行解釋運(yùn)行 的語言。(Java 程序運(yùn)行流程如下)

機(jī)器指令到匯編再到高級(jí)編程語言

 

Java 解釋器 負(fù)責(zé)將字節(jié)碼文件翻譯成具體硬件環(huán)境和操作系統(tǒng)平臺(tái)下的機(jī)器代碼,以便執(zhí)行。因此 Java 程序不能直接運(yùn)行在現(xiàn)有的操作系統(tǒng)平臺(tái)上,它必須運(yùn)行在被稱為 Java 虛擬機(jī)的軟件平臺(tái)之上。

Java 虛擬機(jī)(JVM) 是運(yùn)行 Java 程序的軟件環(huán)境(我們后面會(huì)詳細(xì)說到,這是學(xué)習(xí) Java 繞不過的題),Java 解釋器是 Java 虛擬機(jī)的一部分。在運(yùn)行 Java 程序時(shí),首先會(huì)啟動(dòng) JVM,然后由它來負(fù)責(zé)解釋執(zhí)行 Java 的字節(jié)碼程序,并且 Java 字節(jié)碼程序只能運(yùn)行于 JVM 之上。這樣利用 JVM 就可以把 Java 字節(jié)碼程序和具體的硬件平臺(tái)以及操作系統(tǒng)環(huán)境分隔開來,只要在不同的計(jì)算機(jī)上安裝了針對(duì)特定平臺(tái)的 JVM,Java 程序就可以運(yùn)行,而不用考慮當(dāng)前具體的硬件平臺(tái)及操作系統(tǒng)環(huán)境,也不用考慮字節(jié)碼文件是在何種平臺(tái)上生成的。

JVM 把這種不同軟、硬件平臺(tái)的具體差別隱藏起來,從而 實(shí)現(xiàn)了真正的二進(jìn)制代碼級(jí)的跨平臺(tái)移植。JVM 是 Java 平臺(tái)架構(gòu)的基礎(chǔ),Java 的跨平臺(tái)特性正是通過在 JVM 中運(yùn)行 Java 程序?qū)崿F(xiàn)的。Java 的這種運(yùn)行機(jī)制可以通過下圖來說明:

機(jī)器指令到匯編再到高級(jí)編程語言

 

Java 語言這種「一次編寫,到處運(yùn)行」的方式,有效地解決了目前大多數(shù)高級(jí)程序設(shè)計(jì)語言需要針對(duì)不同系統(tǒng)來編譯產(chǎn)生不同機(jī)器代碼的問題,即硬件環(huán)境和操作平臺(tái)的異構(gòu)問題,大大降低了程序開發(fā)、維護(hù)和管理的開銷。

  • 提示: Java 程序通過 JVM 可以實(shí)現(xiàn)跨平臺(tái)特性,但 JVM 是不跨平臺(tái)的。也就是說,不同操作系統(tǒng)之上的 JVM 是不同的,windows 平臺(tái)之上的 JVM 不能用在 linux 平臺(tái),反之亦然。

參考資料

  1. Introduction to Computer Science using Java | CHAPTER 4 - http://programmedlessons.org/Java9/chap04/ch04_01.html
  2. 匯編語言入門教程 - http://www.ruanyifeng.com/blog/2018/01/assembly-language-primer.html
  3. CPU 是怎么認(rèn)識(shí)代碼的?| 知乎@Zign - https://www.zhihu.com/question/348237008/answer/843382847
  4. 改變世界的代碼行 - https://www.infoq.cn/article/5CaYH8NbS6BmptWKRgkX
  5. The History of FORTRAN - https://www.obliquity.com/computer/fortran/history.html
  6. 《IT 通史》 | @李彥
  7. A Brief Totally Accurate History Of Programming Languages - https://medium.com/commitlog/a-brief-totally-accurate-history-of-programming-languages-cd93ec806124
  8. 編程語言分類 - https://www.cnblogs.com/nickchen121/p/10722720.html

分享到:
標(biāo)簽:編程語言
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定