Ⅰ 編譯原理第三版清華大學
「編譯原理」是計算機專業非常重要的一門專業課,在計算機教學中有著舉足輕重的地位。
編譯原理中編譯系統是整個計算機系統中極其重要的系統軟體,它的作用是把計算機高級語言最終翻譯成等價的計算機指令,從而保證高級程序設計語言順利運行。所以,「編譯原理」是計算機科學中基本研究內容之一。
編譯器:編譯器是計算機程序中應用比較多的工具,在對編譯器進行前端設計時,一定要充分考慮影響因素,還要對詞法、語法、語義進行分析。
過程分析:將高級程序設吾言,如C、C++、java等,翻譯成計算機可以執行的機器指令代碼流的過程,即是編譯的過程。編譯過程一般分為6個步驟,即詞法分析、語法分析、語義分析、中間代碼生成、中間代碼優化、目標代碼生成。
Ⅱ 匯編語言程序設計中使用哪種軟體工具
1、MASM。
微軟公司為x86微處理器家族開發的匯編開發環境,擁有可視化的開發界面,使開發人員不必鄭旅再使用DOS環境進行匯編的開發,編譯速度快,支持80x86匯編以及Win32Asm,是Windows下開發匯編的利喊行凳器。
2、NASM。
全稱The Netwide Assembler,是一款基於80x86和x86-64平台的匯編語言編譯程序,其設計初衷是為了實現編譯器程序跨平台和模塊化的特性。
3、TASM。
Borland公司開發的匯編編譯器,被廣泛用於Turbo C,Quick Basic等編譯器,用作中間過渡編譯。它也能獨立的編譯純匯編或是Win32Asm的代碼。具有編譯快速,高效的特點,至今依然是匯編開發的首選利器。
4、GAS。
GNU匯編器(GNU Assembler),簡稱為GAS,是由GNU計劃所使用的匯編器,GNU的核心精神是自由與分享,所以GAS亦是自由軟體。
5、RadASM。
一款著名的WIN32匯編編輯器,支持MASM、TASM等多種匯編編譯器,Windows界面,支持語法高亮,自帶一個資源編輯器和一個調試器。擁有較強的工程管理功能,加之眾多插件的支持,使得它用匯編語言編寫Windows軟體變得得心應手。
Ⅲ 編譯器的發展史
編譯器編譯器,是將便於人編寫,閱讀,維護的高級計算機語言翻譯為計算機能識別,運行的低級機器語言的程序。編譯器將源程序(Sourcenbsp;program)作為輸入,翻譯產生使用目標語言(Targetnbsp;language)的等價程序。源程序一般為高級語言(High-levelnbsp;language),如Pascal,C++等,而目標語言則是匯編語言或目標機器的目標代碼(Objectnbsp;code),有時也稱作機器代碼(Machinenbsp;code)。一個現代編譯器的主要工作流程如下:源程序(sourcenbsp;code)→預處理器(preprocessor)→編譯器(compiler)→匯編程序(assembler)→目標程序(objectnbsp;code)→連接器(鏈接器,Linker)→可執行程序(executables)nbsp;目錄nbsp;[隱藏]1nbsp;工作原理nbsp;2nbsp;編譯器種類nbsp;3nbsp;預處理器(preprocessor)nbsp;4nbsp;編譯器前端(frontend)nbsp;5nbsp;編譯器後端(backend)nbsp;6nbsp;編譯語言與解釋語言對比nbsp;7nbsp;歷史nbsp;8nbsp;參見nbsp;工作原理翻譯是從源代碼(通常為高級語言)到能直接被計算機或虛擬機執行的目標代碼(通常為低級語言或機器言)。然而,也存在從低級語言到高級語言的編譯器,這類編譯器中用來從由高級語言生成的低級語言代碼重新生成高級語言代碼的又被叫做反編譯器。也有從一種高級語言生成另一種高級語言的編譯器,或者生成一種需要進一步處理的的中間代碼的編譯器(又叫級聯)。典型的編譯器輸出是由包含入口點的名字和地址以及外部調用(到不在這個目標文件中的函數調用)的機器代碼所組成的目標文件。一組目標文件,不必是同一編譯器產生,但使用的編譯器必需採用同樣的輸出格式,可以鏈接在一起並生成可以由用戶直接執行的可執行程序。編譯器種類編譯器可以生成用來在與編譯器本身所在的計算機和操作系統(平台)相同的環境下運行的目標代碼,這種編譯器又叫做「本地」編譯器。另外,編譯器也可以生成用來在其它平台上運行的目標代碼,這種編譯器又叫做交叉編譯器。交叉編譯器在生成新的硬體平台時非常有用。「源碼到源碼編譯器」是指用一種高級語言作為輸入,輸出也是高級語言的編譯器。例如:nbsp;自動並行化編譯器經常採用一種高級語言作為輸入,轉換其中的代碼,並用並行代碼注釋對它進行注釋(如OpenMP)或者用語言構造進行注釋(如FORTRAN的DOALL指令)。預處理器(preprocessor)作用是通過代入預定義等程序段將源程序補充完整。編譯器前端(frontend)前端主要負責解析(parse)輸入的源程序,由詞法分析器和語法分析器協同工作。詞法分析器負責把源程序中的『單詞』(Token)找出來,語法分析器把這些分散的單詞按預先定義好的語法組裝成有意義的表達式,語句nbsp;,函數等等。nbsp;例如「anbsp;=nbsp;bnbsp;+nbsp;c;」前端詞法分析器看到的是「a,nbsp;=,nbsp;bnbsp;,nbsp;+,nbsp;c;」,語法分析器按定義的語法,先把他們組裝成表達式「bnbsp;+nbsp;c」,再組裝成「anbsp;=nbsp;bnbsp;+nbsp;c」的語句。nbsp;前端還負責語義(semanticnbsp;checking)的檢查,例如檢測參與運算的變數是否是同一類型的,簡單的錯誤處理。最終的結果常常是一個抽象的語法樹(abstractnbsp;syntaxnbsp;tree,或nbsp;AST),這樣後端可以在此基礎上進一步優化,處理。編譯器後端(backend)編譯器後端主要負責分析,優化中間代碼(Intermediatenbsp;representation)以及生成機器代碼(Codenbsp;Generation)。一般說來所有的編譯器分析,優化,變型都可以分成兩大類:nbsp;函數內(intraproceral)還是函數之間(interproceral)進行。很明顯,函數間的分析,優化更准確,但需要更長的時間來完成。編譯器分析(compilernbsp;analysis)的對象是前端生成並傳遞過來的中間代碼,現代的優化型編譯器(optimizingnbsp;compiler)常常用好幾種層次的中間代碼來表示程序,高層的中間代碼(highnbsp;levelnbsp;IR)接近輸入的源程序的格式,與輸入語言相關(languagenbsp;dependent),包含更多的全局性的信息,和源程序的結構;中層的中間代碼(middle
Ⅳ 什麼是編譯器
編譯器
編譯器是一種特殊的程序,它可以把以特定編程語言寫成的程序變為機器可以運行的機器碼。我們把一個程序寫好,這時我們利用的環境是文本編輯器。這時我程序把程序稱為源程序。在此以後程序員可以運行相應的編譯器,通過指定需要編譯的文件的名稱就可以把相應的源文件(通過一個復雜的過程)轉化為機器碼了。
[編輯]編譯器工作方法
首先編譯器進行語法分析,也就是要把那些字元串分離出來。然後進行語義分析,就是把各個由語法分析分析出的語法單元的意義搞清楚。最後生成的是目標文件,我們也稱為obj文件。再經過鏈接器的鏈接就可以生成最後的可執行代碼了。有些時候我們需要把多個文件產生的目標文件進行鏈接,產生最後的代碼。我們把一過程稱為交叉鏈接。
一個現代編譯器的主要工作流程如下:
* 源程序(source code)→預處理器(preprocessor)→編譯器(compiler)→匯編程序(assembler)→目標程序(object code)→連接器(鏈接器,Linker)→可執行程序(executables)
工作原理
編譯是從源代碼(通常為高級語言)到能直接被計算機或虛擬機執行的目標代碼(通常為低級語言或機器言)。然而,也存在從低級語言到高級語言的編譯器,這類編譯器中用來從由高級語言生成的低級語言代碼重新生成高級語言代碼的又被叫做反編譯器。也有從一種高級語言生成另一種高級語言的編譯器,或者生成一種需要進一步處理的的中間代碼的編譯器(又叫級聯)。
典型的編譯器輸出是由包含入口點的名字和地址以及外部調用(到不在這個目標文件中的函數調用)的機器代碼所組成的目標文件。一組目標文件,不必是同一編譯器產生,但使用的編譯器必需採用同樣的輸出格式,可以鏈接在一起並生成可以由用戶直接執行的可執行程序。
編譯器種類
編譯器可以生成用來在與編譯器本身所在的計算機和操作系統(平台)相同的環境下運行的目標代碼,這種編譯器又叫做「本地」編譯器。另外,編譯器也可以生成用來在其它平台上運行的目標代碼,這種編譯器又叫做交叉編譯器。交叉編譯器在生成新的硬體平台時非常有用。「源碼到源碼編譯器」是指用一種高級語言作為輸入,輸出也是高級語言的編譯器。例如: 自動並行化編譯器經常採用一種高級語言作為輸入,轉換其中的代碼,並用並行代碼注釋對它進行注釋(如OpenMP)或者用語言構造進行注釋(如FORTRAN的DOALL指令)。
預處理器(preprocessor)
作用是通過代入預定義等程序段將源程序補充完整。
編譯器前端(frontend)
前端主要負責解析(parse)輸入的源程序,由詞法分析器和語法分析器協同工作。詞法分析器負責把源程序中的『單詞』(Token)找出來,語法分析器把這些分散的單詞按預先定義好的語法組裝成有意義的表達式,語句 ,函數等等。 例如「a = b + c;」前端詞法分析器看到的是「a, =, b , +, c;」,語法分析器按定義的語法,先把他們組裝成表達式「b + c」,再組裝成「a = b + c」的語句。 前端還負責語義(semantic checking)的檢查,例如檢測參與運算的變數是否是同一類型的,簡單的錯誤處理。最終的結果常常是一個抽象的語法樹(abstract syntax tree,或 AST),這樣後端可以在此基礎上進一步優化,處理。
編譯器後端(backend)
編譯器後端主要負責分析,優化中間代碼(Intermediate representation)以及生成機器代碼(Code Generation)。
一般說來所有的編譯器分析,優化,變型都可以分成兩大類: 函數內(intraproceral)還是函數之間(interproceral)進行。很明顯,函數間的分析,優化更准確,但需要更長的時間來完成。
編譯器分析(compiler analysis)的對象是前端生成並傳遞過來的中間代碼,現代的優化型編譯器(optimizing compiler)常常用好幾種層次的中間代碼來表示程序,高層的中間代碼(high level IR)接近輸入的源程序的格式,與輸入語言相關(language dependent),包含更多的全局性的信息,和源程序的結構;中層的中間代碼(middle level IR)與輸入語言無關,低層的中間代碼(Low level IR)與機器語言類似。 不同的分析,優化發生在最適合的那一層中間代碼上。
常見的編譯分析有函數調用樹(call tree),控制流程圖(Control flow graph),以及在此基礎上的變數定義-使用,使用-定義鏈(define-use/use-define or u-d/d-u chain),變數別名分析(alias analysis),指針分析(pointer analysis),數據依賴分析(data dependence analysis)等等。
上述的程序分析結果是編譯器優化(compiler optimization)和程序變形(compiler transformation)的前提條件。常見的優化和變新有:函數內嵌(inlining),無用代碼刪除(Dead code elimination),標准化循環結構(loop normalization),循環體展開(loop unrolling),循環體合並,分裂(loop fusion,loop fission),數組填充(array padding),等等。優化和變形的目的是減少代碼的長度,提高內存(memory),緩存(cache)的使用率,減少讀寫磁碟,訪問網路數據的頻率。更高級的優化甚至可以把序列化的代碼(serial code)變成並行運算,多線程的代碼(parallelized,multi-threaded code)。
機器代碼的生成是優化變型後的中間代碼轉換成機器指令的過程。現代編譯器主要採用生成匯編代碼(assembly code)的策略,而不直接生成二進制的目標代碼(binary object code)。即使在代碼生成階段,高級編譯器仍然要做很多分析,優化,變形的工作。例如如何分配寄存器(register allocatioin),如何選擇合適的機器指令(instruction selection),如何合並幾句代碼成一句等等。
Ⅳ 匯編器和編譯器有什麼區別
匯編器(Assembler)是將匯編語言翻譯為機器語言的程序。一般而言,匯編生成的是目標代碼,需要經鏈接器(Linker)生成可執行代碼才可以執行。
匯編語言是一種以處理器指令系統為基礎的低級語言,採用助記符表達指令操作碼,採用標識符表示指令操作數。作為一門語言,對應於高級語言的編譯器,需要一個「匯編器」來把匯編語言原文件匯編成機器可執行的代碼。常用的高級語言編譯器有Microsoft公司的MASM系列和Borland公司的TASM系列編譯器,還有一些小公司推出的或者免費的匯編軟體包等。
編譯器就是將「一種語言(通常為高級語言)」翻譯為「另一種語言(通常為低級語言)」的程序。一個現代編譯器的主要工作流程:源代碼 (source code) → 預處理器 (preprocessor) → 編譯器 (compiler) → 目標代碼 (object code) → 鏈接器(Linker) → 可執行程序 (executables)
高級計算機語言便於人編寫,閱讀交流,維護。機器語言是計算機能直接解讀、運行的。編譯器將匯編或高級計算機語言源程序(Source program)作為輸入,翻譯成目標語言(Target language)機器代碼的等價程序。源代碼一般為高級語言 (High-level language), 如Pascal、C、C++、Java、漢語編程等或匯編語言,而目標則是機器語言的目標代碼(Object code),有時也稱作機器代碼(Machine code)。
對於C#、VB等高級語言而言,此時編譯器完成的功能是把源碼(SourceCode)編譯成通用中間語言(MSIL/CIL)的位元組碼(ByteCode)。最後運行的時候通過通用語言運行庫的轉換,編程最終可以被CPU直接計算的機器碼(NativeCode)
Ⅵ C語言編譯器是用來做什麼的
1.
C語言是一種結構化語言。它層次清晰,便於按模塊化方式組織程序,易於調試和維護。
2.
C語言的表現能力和處理能力極強。它不僅具有豐富的運算符和數據類型,便於實現各類復雜的數據結構。它還可以直接訪問內存的物理地址,進行位(bit)一級的操作。由於C語言實現了對硬體的編程操作,因此C語言集高級語言和低級語言的功能於一體。既可用於系統軟體的開發,也適合於應用軟體的開發。此外,C語言還具有效率高,可移植性強等特點。因此廣泛地移植到了各類各型計算機上,從而形成了多種版本的C語言。
Ⅶ 新人求教,編譯一個最簡單的android程序,提示下面的錯誤咋解決
1、32位系統下的編譯
如果需要在32位系統中編譯android系統,在編譯前需要對部分makefile進行修改
首先修改build/core/main.mk,修改的內容如下所示:
-ifneq (64,$(findstring 64,$(build_arch)))
+ifneq
(i686,$(findstring i686,$(build_arch)))
$(warning
************************************************************) $(warning You are attempting to build on a 32-bit system.)
$(warning Only 64-bit build environments are supported beyond froyo/2.2.)
其次修改如下四個文件:
external/clearsilver/cgi/Android.mk
external/clearsilver/java-jni/Android.mk
external/clearsilver/util/Android.mk
external/clearsilver/cs/Android.mk # This forces a 64-bit build for Java6
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64
+LOCAL_CFLAGS += -m32
+LOCAL_LDFLAGS += -m32即將LOCAL_CFLAGS和LOCAL_LDFLAGS由-m64改為-m32,從而指定使用32位系統進行編譯如果使用 64bit 的操作系統編譯,這些就都不用修改,但記得需要安裝:For 64-bit servers the following extra packages may be needed:
"sudo apt-get install libc6-dev-i386" (libc6-dev-amd64 if AMD CPU)
"sudo apt-get install g++-multilib lib32ncurses5-dev lib32z1-dev"
還有 jdk64bit 的版本編譯2 、build/core/base_rules.mk:128:*** frameworks/opt/emoji/jni:
.... libgl2jni already defined by framwworks/base/opengl/tests/gl2_jni/jni 停止
從編譯規則上看:
# Make sure that this IS_HOST/CLASS/MODULE combination is unique.
mole_id := MODULE.$(if \
$(LOCAL_IS_HOST_MODULE),HOST,TARGET).$(LOCAL_MODULE_CLASS).$(LOCAL_MODULE)
ifdef $(mole_id)
$(error $(LOCAL_PATH): $(mole_id) already defined by $($(mole_id)))
endif
在framwworks/base/opengl/tests/gl2_jni/下面定義的android.mk定義了:
LOCAL_MODULE := libgl2jni
include $(BUILD_SHARED_LIBRARY)
導致生成的動態庫重復,這是不對的,修改tests這個目錄不參與編譯即可,最直接的辦法刪除掉framwworks/base/opengl/tests/gl2_jni這個文件夾
3、AIDL 編譯報couldn't find import for class原因
「AIDL服務只支持有限的數據類型,因此,如果用AIDL服 務傳遞一些復雜的數據就需要做更一步處理。AIDL服務支持的數據類型如下:
Java的簡單類 型(int、char、boolean等)。不需要導入(import)。String和 CharSequence。不需要導入(import)。
List和 Map。但要注意,List和Map對象的元素類型必須是AIDL服務支持的數據類型。不需要導入(import)。AIDL自動生成 的介面。需要導入(import)。
實現 android.os.Parcelable介面的類。需要導入(import)。
其中後兩種數據類 型需要使用import進行導入,傳遞不需要 import的數據類型的值的方式相同。傳遞一個需要import的數據類型的值(例如,實現android.os.Parcelable 介面的類)的步 驟略顯復雜。除了要建立一個實現android.os.Parcelable介面的類外,還需要為這個類單獨建立一個aidl文件,並使用parcelable關鍵字進行定義。」
沒有加LOCAL_AIDL_INCLUDES += xxx ,所以找不到我的parcelable aidl文件。
修改android源碼根目錄下的build/core/pathmap.mk把你的目錄加進去,此時再make update-api
4、老是提示 @Override錯誤 方法未覆蓋其父類的方法
使 用JDK1.6編譯沒有問題,使用JDK1.5編譯,會報@Override方法未覆蓋其父類的方法。實際上這個方法是類實現的介面中方法,
但是,這個語 法的jdk1.6的下面是可以通過的,也就是說jdk1.6認為類覆蓋父類方法與實現介面方法都叫override,而jdk1.5不
是這樣認為的,不知 道這是當初jdk1.5的bug,還是當初就是認為覆蓋父類方法與實現介面方法是不一樣的,不得而知。但是從
OO角度來看,覆蓋父類方法與實現介面方法都 可以認為override,因為他們目的都是一樣的,都是為了重用,都是多態的一種
表現方式。
更改jdk版本為1.6即可
5、編譯alsa-lib庫錯誤
android系統開發移植alsa-lib庫的過程中編譯的時候出現了如下的錯誤
/tmp/cckyaR40.s: Assembler messages:
/tmp/cckyaR40.s:2763: Error: selected processor does not support `mrs ip,cpsr'
/tmp/cckyaR40.s:2764: Error: unshifted register required -- `orr r2,ip,#128'
/tmp/cckyaR40.s:2765: Error: selected processor does not support `msr cpsr_c,r2
字面的意思報的是匯編錯誤,選擇的處理器不支持mrs和msr指令。
原來的ARM指令有32位和16位兩種指令模式,16位為thumb指令集,thumb指令集編譯出的代碼佔用空間小,
而且效率也高,所以android的arm編譯器默認用的是thumb模式編譯,問題在於alsa的代碼中有部分的內容
用到了32位的指令,所以才會報如下的錯誤,修改的方法也很簡單,在Android.mk中加入如下內容即可:
LOCAL_ARM_MODE := arm
android的編譯系統中LOCAL_ARM_MODE變數的取值為arm或者thumb,代表32位和16位兩種arm指令集,默認為thumb
prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/bin/ld: failed to set dynamic section sizes: Bad value
collect2: ld returned 1 exit status
make: *** [out/target/proct/merlin/obj/SHARED_LIBRARIES/libasound_intermediates/LINKED/libasound.so] 錯誤 1
解決此問題將alsa-lib/include/config.h文件中的如下宏定義去掉即可:
#define VERSIONED_SYMBOLS
開發過程中碰到過很多錯誤,後續再一一總結記錄下來,有些忘記了。。
在android.mk中編譯:
include $(CLEAR_VARS)
$(call add-prebuilt-files, STATIC_LIBRARIES, libyfcdca.a)
出現提示需要定義:LOCAL_MODULE_TAGS := optional 一般修改方法是:
build\core\definitions.mk 中的宏定義變數:
define include-prebuilt
include $$(CLEAR_VARS)
LOCAL_SRC_FILES := $(1)
LOCAL_BUILT_MODULE_STEM := $(1)
LOCAL_MODULE_SUFFIX := $$(suffix $(1))
LOCAL_MODULE := $$(basename $(1))
LOCAL_MODULE_CLASS := $(2)
include $$(BUILD_PREBUILT)
endef
在這里增加一個LOCAL_MODULE_TAGS := optional
但是這需要修改android源碼,如果不是自已的android系統,這么做就麻煩了,所以必須想其它辦法解決:
#include $(CLEAR_VARS)
#$(call add-prebuilt-files, STATIC_LIBRARIES, libyfcdca.a)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := libyfcdca.a
LOCAL_BUILT_MODULE_STEM := libyfcdca.a
LOCAL_MODULE_SUFFIX := lib
LOCAL_MODULE := yfcdca
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE_TAGS := optional
include $(BUILD_PREBUILT)
如此即可了。
Ⅷ Java 相關的編譯技術
除了 Java 的編譯器和虛擬機器之外 還有一些相關的編譯技術 本文章試圖做一個簡單的說明 JIT 編譯器 傳統的 Java 虛擬機器很愚蠢 將一道 bytecode 的指令翻譯成機器碼之後 馬上執行這些機器碼 執行完這批機器碼之後 就把這些機器碼丟了 接著再翻譯下一道 bytecode 的指令 繼續下去 即使下次執行到以前執行過的 bytecode 指令 依然要重新翻譯成機器碼才能執行 如此一來 效率當然不好 使用 JIT 編譯器(Just In Time piler)技術的虛擬機器比較聰明 會把常常執行的部分在第一次先翻譯好放在內存 以後再次執行到這里時 就不用再翻譯 直接從內存取出機器碼即可執行 這么一來 只要你的內存夠大 JIT 編譯器的技術夠好 你的 Java bytecode 執行速度也可以逼近純編譯式的程序 其它程序語言的編譯器 任何檔案只要符合 Java bytecode 的格式 就可以被 Java 虛擬機器執行 製造出 Java bytecode 的方式有許多種 不一定要使用 Java 語言來寫程序 才能編譯成 Java bytecode Java 是語言也是平台 你可以不使用 Java 語言(也就是 Java 編譯器) 只使用 Java 平台(也就是 Java 虛擬機器) 只要某語言有提供編譯器 能將該語言的原始碼編譯成 Java bytecode 格式 就可以在 Java 平台上執行 據我所知 目前已經有下列語言提供兼容於 Java 平台的編譯器(以英文字母順序排列) Aardappel Ada Agora BAMBOO Basic Bistro Bolero C C++ CLIPS COBOL Correlate Dawn E EcmaScript Eiffel Foo Forth Fortran Funnel Haskel Hojo javascript Jickle JIF Jinni Lisp LL LLP Logo Luck MINERVA Mini ML Mola NetRexx Nice Oberon Pascal PLAN Pnuts Prolog PS I Python Sather Scheme SELF Simkin Small Talk Tcl WebL Yassl Yoix Yoyo 原生編譯器 如果你不在乎 Java 程序能否跨平台 你希望 Java 程序能如同 C/C++ 一般被編譯成機器碼而非 Java bytecode 那麼你可以使用 Java 原生編譯器(native piler) 目前已經有不少這樣的產品可以使用 Java 原生編譯器有兩大類 一類可以把 Java 的原始碼編譯成機器碼 另一類則可以把 Java bytecode 編譯成機器碼 反編譯與混淆器 Java bytecode 因為檔案格式簡單 信息保留完整 且指令是最簡單的堆棧式(stack based)架構等因素 所以很容易被反編譯(de pilation) 反編譯指的是和編譯相反的過程 對 Java 來說 反編譯就是把 Java bytecode 轉換成 Java 原始碼的過程 為了防止你辛苦地開發出來的 Java bytecode 被他人反編譯成原始碼 你可以透過混淆器(obfuscator)將你的 Java bytecode 轉換成更混亂的 Java bytecode 執行起來效果一樣 但是被混淆過的 Java bytecode 比較不容易被反編譯 你通常要為此付出一點代價 因為混淆過的程序執行速度通常會變慢 且混淆器只能增加反編譯的難度 不能保證你的程序一定無法被反編譯成功 畢竟道高一尺 魔高一丈 如果有人願意花許多時間和精力反編譯你的 Java bytecode 你根本就無法攔阻 組譯與反組譯 匯編語言(assembly)是一種非常接近機器碼的語言 將匯編語言轉成機器碼的工具稱為組譯器(assembler) 反過來將機器碼轉成匯編語言的工具稱為反組譯器(dissembler) 對於 Java 虛擬機器來說 Java bytecode 就如同它的機器碼 有沒有一種語言是很接近 Java bytecode 的呢?也就是說 Java 有沒有的匯編語言呢?基本上 Sun 並未定義 Java 的標准匯編語言 但是有一些人定義了自己的 Java 匯編語言 並提供 Java 的組譯器(甚至反組譯器) 例如 Ja *** in 以及 javaa 都是 Java 組譯器 前處理器 前處理器(pre processor)也稱為前編譯器(pre piler)或前翻譯器(pre translator) 其目的在將源碼中不符合語言規范的部分轉換成符合語言規范的形式 比方說 我們可能在 ??????????Java 源碼中除了使用 Java 語言之外 還穿插使用自訂的語法 這些自訂的語法無法被 Java 編譯器處理 所以我們必須先透過一個前處理器來將自訂語法的部分轉換成 Java 語言 然後就可以交由 Java 編譯器處理 目前有不少 Java 的前處理器 例如 iContract SQLJ 都是用來擴充 Java 語言之用的 最佳化工具軟體 一般來說 最佳化有兩種 讓檔案體積變小 可以節省儲存空間並加快網路傳送速度 讓執行速度變快 對於 Java 來說 還有第三種最佳化 讓程序結構變亂 不容易被反編譯 也就是前面提到過的混淆(obfuscation) 這三個目的之間常常互相排擠 結構變亂 通常會使得程序變慢 且體積變大 體積變小 通常會使得速度變慢 且結構變整齊 速度變快 通常會使得體積變大 且結構變整齊 lishixin/Article/program/Java/hx/201311/27007