[整理]執行引擎,編譯器,概念理解

最近又把《深入理解Java虛擬機》撿起來讀,從引言第一章看對後續章節的總結,看到兩個概念不理解。
一個是執行引擎,一個是編譯器。
格物致知,扔到google裏去搜一下,看維基百科的概念定義。消化理解一下。
這些基本概念,應該是計算機必修課程《編譯原理》裏的,有空需要翻一翻編譯原理了。
(編譯原理–該課程主要講授編譯器設計與實現的主要理論和技術。主要內容包括詞法分析、語法分析、語法樹構造、語義分析、中間代碼生成、代碼優化、目標代碼生成等主要內容。)

執行引擎

虛擬機是一個相對於物理機的概念,物理機執行引擎是基於處理器,硬件,指令集以及操作系統層面上的,而虛擬機引擎完全是有自己實現的,因此格式與結構體系可以自行定製。執行引擎是整個JVM的核心,沒有執行引擎
前面所講的都是白搭。

取自 虛擬機的執行引擎,2018-4,風一樣的行者

JVM的執行引擎
1.運行時棧幀
2.方法的調用(重點)
3. 基於棧的字節碼解釋執行引擎

下邊這一篇分析的更清楚:
深入理解Java虛擬機(字節碼執行引擎),2019-5,掘金,BaronTalk
哇哇哇,今天發現了寶藏,BaronTalk的公衆號真的是排版又好,又有內容。他19年做了一系列java虛擬機的總結,果斷關注。

指令集,wuzguo
編譯優化技術,csdn

編譯器

百度百科:
編譯器將彙編或高級計算機語言源程序(Source program)作爲輸入,翻譯成目標語言(Target language)機器代碼的等價程序。
維基百科:
Compiler (編譯器)
A compiler is a computer program that translates computer code written in one programming language into another language. The name compiler is primarily used for programs that translate source code from a high-level programming language to a lower level language to create an executable program
再看一下阮一峯2014年的博客,編譯器的工作過程, 是對c的編譯過程做了分析。題文第一句,

源碼要運行,必須先轉成二進制的機器碼。這是編譯器的任務。

第一步 配置(configure)
第二步 確定標準庫和頭文件的位置
第三步 確定依賴關係
第四步 頭文件的預編譯(precompilation)
第五步 預處理(Preprocessing)
第六步 編譯(Compilation)
第七步 連接(Linking)
第八步 安裝(Installation)
第九步 操作系統連接
第十步 生成安裝包
第十一步 動態連接(Dynamic linking)

編譯器 vs 解釋器

編譯器的實質是一個 程序。其核心功能是將 源代碼 翻譯成 目標

源代碼: C/C++, Java, …
目標代碼:x86, ARM, …

在這裏插入圖片描述

解釋器 和編譯器相同都是一種程序,源代碼輸入通過編譯器輸出得到的是可執行程序。輸入通過解釋器得到的輸出得到的直接就是一個結果。

相對來說,編譯器是一種離線的模式,解釋器是一種在線的模式。

編譯器結構

由於編譯器實現的是將源代碼轉化爲目標代碼的功能。所以對於編譯器的結構可以大致分爲前端和後端兩部分,前段處理輸入源程序,後端處理輸出目標代碼。
在這裏插入圖片描述
因此,編譯器可以看成是一個由多個階段構成的流水線結構。

如下,給出的是一種沒有優化的編譯器結構。
在這裏插入圖片描述

我們可以看見,最開始的輸入是一個字符序列,也就是沒有處理過的程序代碼。之後進行詞法分析,得到一個記號序列。語法分析接着檢查程序的語法是否合法,在內存中建立一個抽象語法樹的數據結構。之後,進行語義分析,判斷語法樹的合法性,變量是否已經提前聲明,函數是否已經定義…生成中間代碼。最終通過代碼生產得到目標代碼。

靜態編譯,動態編譯

這是C語言的概念?

靜態鏈接庫和動態鏈接庫理解,
靜態編譯:
靜態lib將導出聲明和實現都放在lib中。編譯後所有代碼都嵌入到宿主程序。
動態編譯:
動態lib相當於一個h文件,是對實現部分(.dll文件)的導出部分的聲明。編譯後只是將導出聲明部分編譯到宿主程序中,運行時
候需要相應的dll文件支持。

1.靜態編譯:編譯器在編譯可執行文件時,把需要用到的對應動態鏈接庫(.so或.ilb)中的部分提取出來,鏈接到可執行文件中去,
使可執行文件在運行時不需要依賴於動態鏈接庫.

2.動態編譯: 動態編譯的可執行文件需要附帶一個的動態鏈接庫,在執行時,需要調用其對應動態鏈接庫中的命令。所以其優點一
方面是縮小了執行文件本身的體積,另一方面是加快了編譯速度,節省了系統資源。缺點一是哪怕是很簡單的程序,只用到了鏈接
庫中的一兩條命令,也需要附帶一個相對龐大的鏈接庫;二是如果其他計算機上沒有安裝對應的運行庫,則用動態編譯的可執行文
件就不能運行。

動態鏈接庫:

創建一個動態鏈接庫,會生成x.dll,x.lib
動態鏈接庫有兩種加載方式:
1.一種是靜態加載,就是在編譯的時候就載入動態鏈接庫。此種方法可調用類方法.
可執行程序靜態加載動態鏈接庫需要三個文件 x.dll, x.lib, x.h
可執行程序的頭文件加入:
#include “x.h”
#pragma comment(lib,“x.lib”)
編譯時還要附加庫目錄,防止程序編譯時無法找到x.dll。
2.動態加載
只需要x.dll文件。
在程序執行需要該動態鏈接庫的地方加載x.dll。
然後獲取需要的x.dll庫裏面的函數或數據.
該方法不能調用類方法.

可執行程序調用了動態鏈接庫,其運行不能缺少動態鏈接庫.

靜態鏈接庫:

創建一個靜態鏈接庫,會生成x.lib文件
想要調用靜態鏈接庫裏面的內容需要x.lib文件和x.h文件
庫中內容會直接編譯到x.exe文件中。
可執行程序使用靜態庫編譯成x.exe後,x.exe的運行就不在需要靜態鏈接庫了,可以獨立運行了。

一般的靜態編譯可以理解爲加載靜態鏈接庫;動態編譯理解我加載動態鏈接庫。
靜態鏈接庫中不能包含其他庫,動態鏈接庫中能包含其他庫。

靜態依賴 vs 動態依賴??

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章