程序員使用Java語言實現累加求和的方法,將文件命名爲Sample.java。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; } }
程序員不想直接點擊運行,使用javac編譯了Sample.java文件,能夠看到Sample.java所在的目錄下,生成了Sample.class文件。程序員
那要是彙編語言,具體步驟應該是怎樣的啊?算法
不過,什麼是彙編語言?彙編語言其實和硬件息息相關,也就是脫離不了實際的硬件環境,沒法跨平臺運行,由於彙編語言是人們用助記符表述CPU的動做。CPU結構不同,彙編語言調用的可能也不同。編程
那助記符是什麼意思呢?彙編語言的每一行,表示對CPU的一個指令,其語法結構是操做碼 + 操做數。固然也存在只有操做碼,例如ret,表示將處理返回到函數的調用源。segmentfault
操做碼是對CPU的指令,是動詞,那操做碼是數據,是存儲在CPU的寄存器,是賓語。如mov a b; 表示將b的值賦值給a;add a b; 表示a同b的值相加,並將結果賦值給a。windows
那CPU是否是直接能懂這些助記符嗎?固然不能。微信
咱們知道計算上全部的地址和數據都是由0和1組成的,將彙編語言的那些助記符寫在文本文件上,進行編譯的時候會調用本地計算機上的應用,名爲masm.exe,是一個編譯器。編程語言
將文本文件編譯成目標文件,此時的目標文件成了機器語言,能夠直接被本地的CPU所理解的,若是將這個目標文件由別的計算機的不一樣系列CPU理解,那多是讀不懂,就比如如咱們看不懂火星文。函數
那這個目標文件能夠被本地CPU能夠直接解析運行了嗎?能夠是能夠,可是會直接被報錯。優化
由於咱們僅有這一個目標文件,還不知道這個目標文件和系統的庫文件哪些有關。因此,須要一個連接器,把相關的目標文件組合成一個能夠在特定平臺運行的可執行文件,以下圖:
庫文件名的後綴也是.O或 .OBJ。其中, .ASM .OBJ和 .EXE是在dos或windows系統下的文件, .S和 *.O是在以Linux內核的系統下的文件後綴名,不過Linux內核不靠文件後綴名來判斷這是什麼文件,通常靠文件屬性來判斷,可執行文件在Linux內核中沒有後綴名,用ls命令顯示這個文件是綠色就是可執行文件。
好了,若是是C/C++語言,它的編譯過程應該是怎麼樣子的呢?
預處理 是將要包含(include)的文件插入原文件中、將宏定義展開、根據條件編譯命令選擇要使用的代碼,最後將這些代碼輸出到一個「.i」文件中等待進一步處理;
轉換 是把C/C++代碼(好比上面的".i"文件)「翻譯」成彙編代碼;
編譯 是將用助記符號表示的彙編語言翻譯成符合必定格式的機器語言;
連接 是將彙編生成的OBJ文件、系統庫的OBJ文件、庫文件連接起來,最終生成能夠在特定平臺運行的可執行程序。
好了,寫着寫着忘記Java程序的正事了。
你們所說的Java,有兩個層面意思,一個是做爲編程語言的Java,另外一個是做爲程序運行環境的Java。這就是Java的特殊所在,特殊就特殊在Java有Java虛擬機。
Java程序也須要編譯,可是沒有編譯成機器語言,而是編譯成字節碼文件,而後在Java虛擬機用解釋的方式執行字節碼。
編譯 是將Java源代碼「翻譯」爲Java虛擬機可執行的字節碼文件,保存到硬盤上;
加載 是將生成在內存上的字節碼文件的副本,加載到Java虛擬機上;
Java虛擬機 加載後字節碼後,執行方式有兩種,一種是即時編譯器,另外一種是字節碼解釋器,以下圖:
即時編譯和解釋執行的區別以下:
解釋執行:將編譯好的字節碼一行一行地翻譯爲機器碼執行。 編譯執行:以方法爲單位,將字節碼一次性翻譯爲機器碼後執行。
軟件 是指Java虛擬機對於系統來講,是一個應用,是用某個高級語言編寫的應用。
固然,Java虛擬機對Java程序來講,是一個運行的環境。咱們能夠對比分析一下,把Java源代碼想象成彙編語言源代碼,字節碼想象成本地CPU可執行的機器語言,Java虛擬機想象成本地CPU。
因此這就是爲何說Java是跨平臺的,由於Java虛擬機是一個應用嘛。不過,不一樣的系統,應用也是不一樣的,因此係統不一樣,Java虛擬機也是不一樣的,可是字節碼文件能夠不變的,能夠直接到其它不一樣系統上的虛擬機解析執行的。
Java虛擬機運行的是字節碼,字節碼對Java來講是十六進制;本地CPU執行的是機器碼(機器語言),機器碼對系統來講是二進制。不過,字節碼文件放在本地是0和1組成的,只是不能被本地系統解析執行,須要Java虛擬機即時編譯或解釋執行。
「百聞不如一見」,咱們看看*.class用記事本打開會是怎麼樣的。
這打開是亂碼的啊?這是由於以class爲後綴名的字節碼文件在Java中保存的是十六進制,那咱們要看十六進制如何看呢?
咱們能夠用Sublime Text 3打開字節碼文件,但打開以前Sublime Text 3須要安裝HexViewer插件,才能夠看十六進制的,具體安裝過程能夠到網上搜索。打開以後,以下圖所示:
能夠看到全部的數字都是十六進制的,接下來下一步就加載到Java虛擬機上去了,具體用即時編譯的仍是解釋執行的,或者在大項目中即時編譯和解釋執行都是能夠共同打配合的,由於Java虛擬機在不一樣的場景下用的是不一樣的優化手段。
喜歡本文的朋友,微信搜索「算法無遺策」公衆號,收看更多精彩的算法動畫文章