程序員想知道代碼是怎樣跑起來的

程序員使用Java語言實現(xiàn)累加求和的方法墅垮,將文件命名為Sample.java。

public class Sample {
    public static void main(String[] args) {
        System.out.println(sum(10));
    }

    private static int sum(int n) {
        int res = 0;
        for (int i = 1; i < n; i++) {
            res += i;
        }
        return res;
    }
}

程序員不想直接點(diǎn)擊運(yùn)行耕漱,使用javac編譯了Sample.java文件算色,可以看到Sample.java所在的目錄下,生成了Sample.class文件螟够。

那要是匯編語言灾梦,具體步驟應(yīng)該是怎樣的啊妓笙?

不過若河,什么是匯編語言?匯編語言其實和硬件息息相關(guān)寞宫,也就是脫離不了實際的硬件環(huán)境萧福,無法跨平臺運(yùn)行,因為匯編語言是人們用助記符表述CPU的動作辈赋。CPU結(jié)構(gòu)不一樣统锤,匯編語言調(diào)用的可能也不一樣。

那助記符是什么意思呢炭庙?匯編語言的每一行饲窿,表示對CPU的一個指令,其語法結(jié)構(gòu)是操作碼 + 操作數(shù)焕蹄。當(dāng)然也存在只有操作碼逾雄,例如ret,表示將處理返回到函數(shù)的調(diào)用源。

操作碼是對CPU的指令鸦泳,是動詞银锻,那操作碼是數(shù)據(jù),是存儲在CPU的寄存器做鹰,是賓語击纬。如mov a b; 表示將b的值賦值給a;add a b; 表示a同b的值相加钾麸,并將結(jié)果賦值給a更振。

那CPU是不是直接能懂這些助記符嗎?當(dāng)然不能饭尝。

我們知道計算上所有的地址和數(shù)據(jù)都是由0和1組成的肯腕,將匯編語言的那些助記符寫在文本文件上,進(jìn)行編譯的時候會調(diào)用本地計算機(jī)上的應(yīng)用钥平,名為masm.exe实撒,是一個編譯器。

將文本文件編譯成目標(biāo)文件涉瘾,此時的目標(biāo)文件成了機(jī)器語言知态,可以直接被本地的CPU所理解的,如果將這個目標(biāo)文件由別的計算機(jī)的不同系列CPU理解立叛,那可能是讀不懂肴甸,就好比如我們看不懂火星文。

那這個目標(biāo)文件可以被本地CPU可以直接解析運(yùn)行了嗎囚巴?可以是可以原在,但是會直接被報錯。

因為我們僅有這一個目標(biāo)文件彤叉,還不知道這個目標(biāo)文件和系統(tǒng)的庫文件哪些有關(guān)庶柿。所以,需要一個鏈接器秽浇,把相關(guān)的目標(biāo)文件組合成一個可以在特定平臺運(yùn)行的可執(zhí)行文件浮庐,如下圖:

匯編語言

庫文件名的后綴也是*.O或 *.OBJ。其中柬焕, *.ASM *.OBJ和 *.EXE是在dos或windows系統(tǒng)下的文件审残, *.S和 *.O是在以Linux內(nèi)核的系統(tǒng)下的文件后綴名,不過Linux內(nèi)核不靠文件后綴名來判斷這是什么文件斑举,一般靠文件屬性來判斷搅轿,可執(zhí)行文件在Linux內(nèi)核中沒有后綴名,用ls命令顯示這個文件是綠色就是可執(zhí)行文件富玷。

好了璧坟,如果是C/C++語言既穆,它的編譯過程應(yīng)該是怎么樣子的呢?

C語言編譯器過程

預(yù)處理 是將要包含(include)的文件插入原文件中雀鹃、將宏定義展開幻工、根據(jù)條件編譯命令選擇要使用的代碼,最后將這些代碼輸出到一個“.i”文件中等待進(jìn)一步處理黎茎;

轉(zhuǎn)換 是把C/C++代碼(比如上面的".i"文件)“翻譯”成匯編代碼囊颅;

編譯 是將用助記符號表示的匯編語言翻譯成符合一定格式的機(jī)器語言;

鏈接 是將匯編生成的OBJ文件傅瞻、系統(tǒng)庫的OBJ文件踢代、庫文件鏈接起來,最終生成可以在特定平臺運(yùn)行的可執(zhí)行程序俭正。

好了,寫著寫著忘記Java程序的正事了焙畔。

大家所說的Java掸读,有兩個層面意思,一個是作為編程語言的Java宏多,另一個是作為程序運(yùn)行環(huán)境的Java儿惫。這就是Java的特殊所在,特殊就特殊在Java有Java虛擬機(jī)伸但。

Java程序也需要編譯肾请,但是沒有編譯成機(jī)器語言,而是編譯成字節(jié)碼文件更胖,然后在Java虛擬機(jī)用解釋的方式執(zhí)行字節(jié)碼铛铁。

Java虛擬機(jī)

編譯 是將Java源代碼“翻譯”為Java虛擬機(jī)可執(zhí)行的字節(jié)碼文件却妨,保存到硬盤上;

加載 是將生成在內(nèi)存上的字節(jié)碼文件的副本彪标,加載到Java虛擬機(jī)上;

Java虛擬機(jī) 加載后字節(jié)碼后捞烟,執(zhí)行方式有兩種薄声,一種是即時編譯器,另一種是字節(jié)碼解釋器题画,如下圖:

Java虛擬機(jī)執(zhí)行引擎

即時編譯和解釋執(zhí)行的區(qū)別如下:

解釋執(zhí)行:將編譯好的字節(jié)碼一行一行地翻譯為機(jī)器碼執(zhí)行苍息。

編譯執(zhí)行:以方法為單位廓奕,將字節(jié)碼一次性翻譯為機(jī)器碼后執(zhí)行抱婉。

軟件 是指Java虛擬機(jī)對于系統(tǒng)來說,是一個應(yīng)用桌粉,是用某個高級語言編寫的應(yīng)用蒸绩。

當(dāng)然铃肯,Java虛擬機(jī)對Java程序來說,是一個運(yùn)行的環(huán)境押逼。我們可以對比分析一下,把Java源代碼想象成匯編語言源代碼咙冗,字節(jié)碼想象成本地CPU可執(zhí)行的機(jī)器語言漂彤,Java虛擬機(jī)想象成本地CPU雾消。

所以這就是為什么說Java是跨平臺的挫望,因為Java虛擬機(jī)是一個應(yīng)用嘛。不過媳板,不同的系統(tǒng),應(yīng)用也是不同的破讨,所以系統(tǒng)不同奕纫,Java虛擬機(jī)也是不同的,但是字節(jié)碼文件可以不變的若锁,可以直接到其它不同系統(tǒng)上的虛擬機(jī)解析執(zhí)行的。

Java虛擬機(jī)運(yùn)行的是字節(jié)碼又固,字節(jié)碼對Java來說是十六進(jìn)制;本地CPU執(zhí)行的是機(jī)器碼(機(jī)器語言)乏冀,機(jī)器碼對系統(tǒng)來說是二進(jìn)制洋只。不過辆沦,字節(jié)碼文件放在本地是0和1組成的昼捍,只是不能被本地系統(tǒng)解析執(zhí)行,需要Java虛擬機(jī)即時編譯或解釋執(zhí)行妒茬。

“百聞不如一見”蔚晨,我們看看*.class用記事本打開會是怎么樣的。

記事本

這打開是亂碼的懊蟆?這是因為以class為后綴名的字節(jié)碼文件在Java中保存的是十六進(jìn)制浩考,那我們要看十六進(jìn)制如何看呢被盈?

我們可以用Sublime Text 3打開字節(jié)碼文件,但打開之前Sublime Text 3需要安裝HexViewer插件害捕,才可以看十六進(jìn)制的闷畸,具體安裝過程可以到網(wǎng)上搜索。打開之后盾沫,如下圖所示:

Sublime Text 3

可以看到所有的數(shù)字都是十六進(jìn)制的殿漠,接下來下一步就加載到Java虛擬機(jī)上去了,具體用即時編譯的還是解釋執(zhí)行的蕾哟,或者在大項目中即時編譯和解釋執(zhí)行都是可以共同打配合的莲蜘,因為Java虛擬機(jī)在不同的場景下用的是不同的優(yōu)化手段。
喜歡本文的朋友票渠,微信搜索「算法無遺策」公眾號,收看更多精彩的算法動畫文章

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末昂秃,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子肠骆,更是在濱河造成了極大的恐慌,老刑警劉巖郊艘,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唯咬,死亡現(xiàn)場離奇詭異,居然都是意外死亡狞贱,警方通過查閱死者的電腦和手機(jī)蜀涨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厚柳,“玉大人,你說我怎么就攤上這事便监√枷耄” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵逊移,是天一觀的道長。 經(jīng)常有香客問我胳泉,道長岩遗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任钳吟,我火速辦了婚禮窘拯,結(jié)果婚禮上红且,老公的妹妹穿的比我還像新娘。我一直安慰自己嗤放,他們只是感情好壁酬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著岳服,像睡著了一般希俩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上颜武,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機(jī)與錄音这吻,去河邊找鬼篙议。 笑死唾糯,一個胖子當(dāng)著我的面吹牛涡上,可吹牛的內(nèi)容都是我干的拒名。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼雁佳,長吁一口氣:“原來是場噩夢啊……” “哼同云!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起炸站,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤旱易,失蹤者是張志新(化名)和其女友劉穎腿堤,沒想到半個月后如暖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笆檀,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡酗洒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年枷遂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片箫老。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡黔州,死狀恐怖流妻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情涣达,我是刑警寧澤证薇,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布浑度,位于F島的核電站,受9級特大地震影響箩张,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜饮笛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一福青、第九天 我趴在偏房一處隱蔽的房頂上張望无午。 院中可真熱鬧,春花似錦指厌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至钠龙,卻和暖如春御铃,著一層夾襖步出監(jiān)牢的瞬間上真,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工根竿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寇壳,地道東北人妻怎。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓蹂季,卻偏偏與公主長得像偿洁,于是被迫代替她去往敵國和親沟优。 傳聞我的和親對象是個殘疾皇子挠阁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容