① 編譯器是什麼。
1、 visual c++6.0 (win8系統下不好用,C/C++)-Microsoft Visual C++ ;
2、 visual studio (2005、2008、2010、2012、2013)- Microsoft Visual Studio ;
3、 win-tc非常方便:不騙你,2000/XP/7都可以用 ;
4、 Code::Blocks(win7、8都可以用);
5、 Turb C(只能編譯C語言) ;
6、 gcc (GNU編譯器套件) ;
7、 DEV C++;
8、 C-Free;
9、 Borland C++、WaTCom C++、Borland C++ Builder、GNU DJGPP C++、Lccwin32 C Compiler3.1、High C、My Tc等,由於C語言比較成熟,所以編程環境很多;
10、還常用souceinsight ,在工作中還用Labwindows編程,直接調試運行,不過那是有工程背景,有工作經驗的技術人員用的。
② uC/OS II移植到ARM,其中,OSTickISR()函數的匯編代碼
控制器上運行。為了方便移植,大部分的µC/OS-Ⅱ代碼是用C語言寫的;但仍需要用C和匯編語言寫一些與處理器相關的代碼,這是因為µC/OS-Ⅱ在讀寫處理器寄存器時只能通過匯編語言來實現。由於µC/OS-Ⅱ在設計時就已經充分考慮了可移植性,所以µC/OS-Ⅱ的移植相對來說是比較容易的。[5,6]
要使µC/OS-Ⅱ正常運行,處理器必須滿足以下要求:
(1) 處理器的C編譯器能產生可重入代碼。
(2) 用C語言就可以打開和關閉中斷。
(3) 處理器支持中斷,並且能產生定時中斷(通常在10至100Hz之間)。
(4) 處理器支持能夠容納一定量數據(可能是幾千位元組)的硬體堆棧。
(5) 處理器有將堆棧指針和其它CPU寄存器讀出和存儲的指令
圖2-1說明了µC/OS-Ⅱ的結構以及它與硬體的關系。從圖中可以看到整個系統的架構。最底層是硬體層,該層主要涉及到CPU處理器的架設,以及它與外部各功能模塊的連接,對於CPU處理器的初始化也是構架嵌入式系統的重要內容,特別是對定時器的設置,將是構建操作系統的基礎,它決定整個系統的性能。對於軟體部分,最底層是與處理器相關的程序代碼,該段代碼直接對CPU處理器進行初始化,這部分代碼就是移植操作系統的主要內容,也是最難以理解的部分。這段代碼絕大部分程序是用匯編語言編寫的,因為在程序運行的時候,這部分代碼的調用次數最頻繁。在向上的代碼就與處理器沒有任何的關系,其中一部分包括操作系統的配置文件,像OS_CORE.c,OS_FLAG.c等文件。這部分代碼是用來編寫一些基本的底層函數,這些函數將作為以後應用部分的基本函數庫進行調用,這部分函數構成了操作系統的基本構架,不同的操作系統所對應的系統的設計思想不同,主要體現在這些函數的設計中。除了系統的基本函數外,還有應用部分的基本配置文件。該文件聲明的是與具體的應用配置有關的一些設置文件。比如,各任務的一些基本參數,所使用的信號量的聲明,以及液晶的參數配置等。不同的應用程序對應的該文件參數配置也不同。有了底層的基本配置文件,就可以編寫具體的應用程序了,最上層就是應用程序,針對不同的應用需求,編寫不同的應用程序。
μCOS-II不使用C語言中的short、int、long等數據類型的定義,因為它們與處理器類型有關,隱含著不可移植性。代之以移植性強的整數數據類型,這樣,既直觀又可移植,不過這就成了必須移植的代碼。根據ADS編譯器的特性,這些代碼如程序清單圖2-2所示。
與所有的實時內核一樣,µC/OS-Ⅱ需要先禁止中斷再訪問代碼的臨界段,並且在訪問完畢後重新允許中斷。這就使得µC/OS-Ⅱ能夠保護臨界段代碼免受多任務或中斷服務常式(ISRs)的破壞。為了隱藏編譯器廠商提供的具體實現方法,µC/OS-Ⅱ定義了兩個宏來禁止和允許中斷:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。
μCOS-II使用結構常量OS_STK_GROWTH中指定堆棧的生長方式:置OS_STK_GROWTH為0表示堆棧從下往上長。置OS_STK_GROWTH為1表示堆棧從上往下長。雖然ARM處理器核對於兩種方式均支持,但ADS的C語言編譯器僅支持一種方式,即從上往下長,並且必須是滿遞減堆棧,所以OS_STK_GROWTH的值為1。
µC/OS-Ⅱ的移植實例要求用戶編寫四個簡單的匯編語言函數: OSStartHighRdy();OSCtxSw();OSIntCtxSw();OSTickISR()。如果用戶的編譯器支持插入匯編語言代碼的話,用戶就可以將所有與處理器相關的代碼放到OS_CPU_C.C文件中,而不必再擁有一些分散的匯編語言文件。
使就緒狀態的任務開始運行的函數叫做OSStart(),如下示意函數所示。在用戶調用OSStart()之前,用戶必須至少已經建立了一個任務。OSStartHighRdy()假設OSTCBHighRdy指向的是優先順序最高的任務的任務控制塊。為了簡單一點,堆棧指針總是儲存在任務控制塊(即它的OS_TCB)的開頭。換句話說,也就是要想恢復的任務堆棧指針總是儲存在OS_TCB的0偏址內存單元中。
如果當前任務調用µC/OS-Ⅱ提供的系統服務,並使得更高優先順序任務處於就緒狀態,µC/OS-Ⅱ就會藉助上面提到的向量地址找到OSCtxSw()。在系統服務調用的最後,µC/OS-Ⅱ會調用OSSched(),並由此來推斷當前任務不再是要運行的最重要的任務了。軟中斷 (或陷阱) 指令會強制一些處理器寄存器(比如返回地址和處理器狀態字)到當前任務的堆棧中,並使處理器執行OSCtxSw()。這些代碼必須寫在匯編語言中,因為用戶不能直接從C中訪問CPU寄存器。注意在OSCtxSw()和用戶定義的函數OSTaskSwHook()的執行過程中,中斷是禁止的。
OSIntExit()通過調用OSIntCtxSw()來從ISR中執行切換功能。因為OSIntCtxSw()是在ISR中被調用的,所以可以斷定所有的處理器寄存器都被正確地保存到了被中斷的任務的堆棧之中。實際上除了需要的東西外,堆棧結構中還有其它的一些東西。OSIntCtxSw()必須要清理堆棧,這樣被中斷的任務的堆棧結構內容才能滿足人們的需要。
要想了解OSIntCtxSw(),大家可以看看µC/OS-Ⅱ調用該函數的過程。假定中斷不能嵌套(即ISR不會被中斷),中斷是允許的,並且處理器正在執行任務級的代碼。當中斷來臨的時候,處理器會結束當前的指令,識別中斷並且初始化中斷處理過程,包括將處理器的狀態寄存器和返回被中斷的任務的地址保存到堆棧中。至於究竟哪些寄存器保存到了堆棧上,以及保存的順序是怎樣的,並不重要。
接著,CPU會調用正確的ISR。µC/OS-Ⅱ要求ISR在開始時要保存剩下的處理器寄存器。一旦寄存器保存好了,µC/OS-Ⅱ就要求或者調用OSIntEnter(),或者將變數OSIntNesting加1。在這個時候,被中斷任務的堆棧中只包含了被中斷任務的寄存器內容。現在,ISR可以執行中斷服務了。並且如果ISR發消息給任務(通過調用OSMboxPost()或OSQPost()),恢復任務(通過調用OSTaskResume()),或者調用OSTimeTick()或OSTimeDlyResume()的話,有可能使更高優先順序的任務處於就緒狀態。
假設有一個更高優先順序的任務處於就緒狀態。µC/OS-Ⅱ要求用戶的ISR在完成中斷服務的時候調用OSIntExit()。OSIntExit()會告訴µC/OS-Ⅱ到了返回任務級代碼的時間了。調用OSIntExit()會導致調用者的返回地址被保存到被中斷的任務的堆棧中。
OSIntExit()剛開始時會禁止中斷,因為它需要執行臨界段的代碼。根據OS_ENTER_CRITICAL()的不同執行過程,處理器的狀態寄存器會被保存到被中斷的任務的堆棧中。OSIntExit()注意到由於有更高優先順序的任務處於就緒狀態,被中斷的任務已經不再是要繼續執行的任務了。在這種情況下,指針OSTCBHighRdy會被指向新任務的OS_TCB,並且OSIntExit()會調用OSIntCtxSw()來執行任務切換。調用OSIntCtxSw()也同樣使返回地址被保存到被中斷的任務的堆棧中。
用戶切換任務的時候,用戶只想將某些項保留在堆棧中,並忽略其它項。這是通過調整堆棧指針(加一個數在堆棧指針上)來完成的。加在堆棧指針上的數必須是明確的,而這個數主要依賴於移植的目標處理器(地址空間可能是16,32或64位),所用的編譯器,編譯器選項,內存模式等等。另外,處理器狀態字可能是8,16,32甚至64位寬,並且OSIntExit()可能會分配局部變數。有些處理器允許用戶直接增加常量到堆棧指針中,而有些則不允許。在後一種情況下,可以通過簡單的執行一定數量的pop(出棧)指令來實現相同的功能。一旦堆棧指針完成調整,新的堆棧指針會被保存到被切換出去的任務的OS_TCB中。
這些代碼必須寫在匯編語言中,因為用戶不能直接從C語言中訪問CPU寄存器。如果用戶的編譯器支持插入匯編語言代碼的話,用戶就可以將OSIntCtxSw()代碼放到OS_CPU_C.C文件中,而不放到OS_CPU_A.ASM文件中。正如用戶所看到的那樣,除了第一行以外,OSIntCtxSw()的代碼與OSCtxSw()是一樣的。這樣在移植實例中,用戶可以通過「跳轉」到OSCtxSw()中來減少OSIntCtxSw()代碼量。
µC/OS-Ⅱ要求用戶提供一個時鍾資源來實現時間的延時和期滿功能。時鍾節拍應該每秒鍾發生10-100次。為了完成該任務,可以使用硬體時鍾,也可以從交流電中獲得50/60Hz的時鍾頻率。
這些代碼必須寫在匯編語言中,因為用戶不能直接從C語言中訪問CPU寄存器。如果用戶的處理器可以通過單條指令來增加OSIntNesting,那麼用戶就沒必要調用OSIntEnter()了。增加OSIntNesting要比通過函數調用和返回快得多。OSIntEnter()只增加OSIntNesting,並且作為臨界段代碼中受到保護。
µC/OS-Ⅱ的移植實例要求用戶編寫六個簡單的C函數:OSTaskStkInit(); OSTaskCreateHook();OSTaskDelHook();OSTaskSwHook();OSTaskStatHook(); OSTimeTickHook()。唯一必要的函數是OSTaskStkInit(),其它五個函數必須得聲明但沒必要包含代碼。
OSTaskCreate()和OSTaskCreateExt()通過調用OSTaskStkInt()來初始化任務的堆棧結構,因此,堆棧看起來就像剛發生過中斷並將所有的寄存器保存到堆棧中的情形一樣。顯示了OSTaskStkInt()放到正被建立的任務堆棧中的東西。注意,在這里我假定了堆棧是從上往下長的。下面的討論同樣適用於從下往上長的堆棧。
在用戶建立任務的時候,用戶會傳遞任務的地址,pdata指針,任務的堆棧棧頂和任務的優先順序給OSTaskCreate()和OSTaskCreateExt()。雖然OSTaskCreateExt()還要求有其它的參數,但這些參數在討論OSTaskStkInt()的時候是無關緊要的。為了正確初始化堆棧結構,OSTaskStkInt()只要求剛才提到的前三個參數和一個附加的選項,這個選項只能在OSTaskCreateExt()中得到。
該函數主要是對相關的幾個寄存器進行初始化工作,初始化的寄存器對應於
③ 如何用編譯器將自己的源代碼轉換成目標代碼
我們使用編譯器將自己的源代碼轉換成目標代碼,
使用鏈接器將我們的目標代碼鏈接成一個可執行程序。另外,
我們使用一些程序在計算機中輸入源代碼文本並且編輯它。這些是最初的和最重要的工具,
它們構成程序員的工具集合或「程序開發環境」。
如果你使用的是命令行窗口,
就像很多專業程序員所做的那樣,
你將不得不自己來編寫編譯和鏈接命令。如果你使用IDE(「互動式開發環境」或「集成式開發環境」),
就像很多程序員所做的那樣,
簡單地點擊正確按鈕就可以完成這個工作。附錄C介紹了如何在你的C++實現中編譯和鏈接。
IDE通常包括一個具有有用特性的編輯器,
例如用不同顏色的代碼來區分你的源代碼中的注釋、
關鍵字和其他部分,
以及其他幫助你來調試代碼、
編譯和運行代碼的功能。調試是發現程序中的錯誤和排除錯誤的活動,
你在前進的道路上會聽到很多有關它的內容。
我們使用微軟的Visual
C++作?喑炭
⒒肪呈道
H綣
頤羌虻サ廝怠氨嘁肫鰲被蚴恰癐DE」的某些部分,
那就是所指Visual
C++系統。但是,
你可以使用一些提供最新的、
符合標準的C++實現的系統。我們所說的大多數內容(經過微小的修改)對所有的C++實現都將是正確的,
並且其代碼可以在任何地方運行。在工作中,
我們使用幾種不同的實現。
④ 可重入代碼的其他不同的解釋
可重入就是,一個函數沒有執行完成,由於外部因素或內部調用,又一次進入該函數執行。可重入代碼,必須保證資源的互不影響的使用,比如全局變數,系統資源等。 在LINUX設備驅動中 關於可重入代碼:
簡單介紹,因為驅動能夠被多個進程調用,互不幹擾,這樣驅動必須是可重入的。
可重入最簡單的理解就是任何變數都是局部變數。可重入指函數在運行過程中,被中斷打斷後,待返回時仍然能夠正常運行。這就需要在編寫代碼時注意全局變數和公用資源的使用,同時還需要有編譯器的支持。否則,ucos ii就不能移植到其中了!!
⑤ 陽初s3c2410 如何初始化
點 隨著信息化技術的發展和數字化產品的普及,以計算機技術、晶元技術和軟體技術為核心的嵌入式系統再度成為當前研究和應用的熱點。對功能、可靠性、成本、體積和功耗嚴格要求的嵌入式系統一般由嵌入式微處理器、外圍硬體設備、嵌入式操作系統以及用戶的應用程序等四個部分組成,其中嵌入式微處理器和嵌入式操作系統分別是其硬體和軟體的核心。
ARM處理器由於其具有小體積、低功耗、低成本、高性能等特點,廣泛應用在16/32位嵌入式RISC解決方案中,幾乎佔有嵌入式微處理器市場分額的75% ,本文選定三星公司生產的一款基於ARM920T核的高性能低功耗SOC晶元S3C2410作為移植方案的硬體平台。市場上主流的嵌入式實時操作系統有Vxworks、pSos、WinCE、Linux等,基於實時性、成本以及開發難度方面的考慮,我們選擇uC/OS II——開放源代碼的嵌入式實時操作系統。
1 uC/OS II介紹
uC/OS II(Micro Control Operation System Two)是一個可以基於ROM運行的、可裁減的、搶占式(見圖1)實時多任務內核,具有高度可移植性,特別適合於微處理器和控制器,是和很多商業操作系統性能相當的實時操作系統(RTOS)。為了提供最好的移植性能,uC/OS II最大程度上使用ANSI C語言進行開發,並且已經移植到近40多種處理器體繫上,涵蓋了從8位到64位各種CPU(包括DSP)。
uC/OS II可以簡單的視為一個多任務調度器,在這個任務調度器之上完善並添加了和多任務操作系統相關的系統服務,如信號量、郵箱等。其主要特點有公開源代碼,代碼結構清晰、明了,注釋詳盡,組織有條理,可移植性好,可裁剪,可固化。內核屬於搶占式,最多可以管理60個任務。從1992年開始,由於高度可靠性、魯棒性和安全性,uC/OS II已經廣泛使用在從照相機到航空電子產品的各種應用中。
2 uC/OS II在S3C2410上的可移植性
所謂移植,就是使這個實時內核能在某個微處理器上運行。為了方便移植,大部分的uC/OS II代碼是用c語言寫的,但仍需要用c和匯編語言寫一些與處理器相關的代碼,這是因為uC/OS II在讀寫處理器寄存器時只能通過匯編語言來實現。由於uC/OS II在設計時就已經充分考慮了可移植性,所以uC/OS II的移植相對來說是比較容易的。uC/OS II的框架結構如圖2。
uC/OSII的正常運行需要處理器平台滿足以下要求:
a)處理器的C編譯器能產生可重入代碼。
b)用C語言就可以打開和關閉中斷。
c)處理器支持中斷,並且能產生定時中斷(通常在10至100Hz之間)。
d)處理器支持能夠容納一定量數據(可能是幾千位元組)的硬體堆棧。
e)處理器有將堆棧指針和其它CPU寄存器讀出和存儲到堆棧或內存中的指令。
S3C2410處理器採用ARM920T內核,內部共有37個寄存器,其中R13通常用作堆棧指針,只要系統RAM空間允許,堆棧空間理論上沒有限制。ARM處理器提供ARM指令和Thumb指令兩種指令集,每種指令集都包含有豐富的指令對堆棧進行操作,可以隨意的對處理器中的寄存器進行堆棧操作。根據堆棧生長方向的不同,可以生成4種不同的堆棧,分別是滿遞增、空遞增、滿遞減(此移植中使用的是滿遞減方式)、空遞減。晶元內集成5個定時時鍾,任何一個都可以產生定時中斷,滿足第三條要求。ADS集成開發環境的內置編譯器可以產生可重入代碼,並且支持內嵌匯編,C環境中可任意的進行開關中斷操作。綜上所述uC/OS II完全可以移植到S3C2410上運行。
3 主體移植過程
3.1 設置與處理器及編譯器相關的代碼[OS_CPU.H]
不同的編譯器會使用不同的位元組長度來表示同一數據類型,所以要定義一系列數據類型以確保移植的正確性。下面是uC/OS II定義的一部分數據類型。
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U;/*無符號8位*/
typedef signed char INT16S;/*帶符號8位*/
typedef unsigned int INT16U;/*無符號16位*/
typedef signed int INT16S;/*帶符號16位*/
typedef unsigned long INT32U;/*無符號32位數*/
typedef signed long INT32S;/*帶符號32位數*/
typedef float FP32;/*單精度浮點數*/
typedef double FP64;/*雙精度浮點數*/
typedef unsigned int OS_STK;/*堆棧入口寬度*/
typedef unsigned int OS_CPU_SR;/*寄存器寬度*/
uC/OS II需要先關中斷再訪問臨界區的代碼,並且在訪問完後重新允許中斷。uC/OS II定義了兩個宏來禁止和允許中斷:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL(),本移植實現這兩個宏的匯編代碼。
#define OS_ENTER_CRITICAL()(cpu_sr=OSCPUSaveSR())/*Disable interrupts*/
#define OS_EXIT_CRITICAL()(OSCPURestoreSR(cpu_sr))/*Enable interrupts*/
EXPORT OSCPUSaveSR
OSCPUSaveSR
mrs r1,cpsr
mov r0,r1
orr r1,r1,#0xc0
msr cpsr_cxsf,r1
mov pc,lr
EXPORT OSCPURestoreSR
OSCPURestoreSR
msr cpsr_cxsf,r0
mov pc,lr
3.2 用C語言實現與處理器任務相關的函數[OS_CPU_C.C]
OSTaskStkInit()
OSTaskCreateHook()
OSTaskDelHook()
OSTaskSwHook()
OSTaskStatHook()
OSTimeTickHook()
實際需要修改的只有OSTaskStkInit()函數,其他五個函數需要聲明,但不一定有實際內容。這五個函數都是用戶定義的,所以OS_CPU_C.C中沒有給出代碼。如果需要使用這些函數,可以將文件OS_CFG.H中的#define constant OS_CPU_HOOKS_EN設為1,設為0表示不使用這些函數。
OSTaskStkInit()函數由OSTaskCreate()或OSTaskCreateExt()調用,需要傳遞的參數是任務代碼的起始地址、參數指針(pdata)、任務堆棧頂端的地址和任務的優先順序,用來初始化任務的堆棧,初始狀態的堆棧模擬發生一次中斷後的堆棧結構。堆棧初始化工作結束後,OSTaskStkInit()返回新的堆棧棧頂指針,OSTaskCreate()或OSTaskCreateExt()將指針保存在任務的OS_TCB中。調用OSTaskStkInit()給任務做一個初始的任務上下文堆棧,形狀如圖3。
3.3 處理器相關部分匯編實現
整個uC/OS II移植實現中,只需要提供一個匯編語言文件,提供幾個必須由匯編才能實現的函數。
a)OSStartHighRdy()
該函數在OSStart()多任務啟動之後,負責從最高優先順序任務的TCB控制塊中獲得該任務的堆棧指針sp,通過sp依次將CPU現場恢復,此時系統就將控制權交給用戶創建的該任務的進程,直到該任務被阻塞或者被其他更高優先順序的任務搶佔了CPU。該函數僅僅在多任務啟動時被執行一次,用來啟動第一個,也就是最高優先順序的任務執行。
b)OSCtxSw()
該函數是任務級的上下文切換函數,在任務因為被阻塞而主動請求與CPU調度時執行,主要工作是先將當前任務的CPU現場保存到該任務堆棧中,然後獲得最高優先順序任務的堆棧指針,從該堆棧中恢復此任務的CPU現場,使之繼續執行,從而完成一次任務切換。
C)OSIntExit()
該函數是中斷級的任務切換函數,在時鍾中斷ISR中發現有高優先順序任務在等待時,需要在中斷退出後不返回被中斷的任務,而是直接調度就緒的高優先順序任務執行。其目的在於能夠盡快讓高優先順序的任務得到響應,保證系統的實時性能。
d)OSTickISR()
該函數是時鍾中斷處理函數,主要任務是負責處理時鍾中斷,調用系統實現的OSTimeTick函數,如果有等待時鍾信號的高優先順序任務,則需要在中斷級別上調度其執行。另外兩個相關函數是OSIntEnter()和OSIntExit(),都需要在ISR中執行。
4 測試
至此代碼移植過程已經完成,下一步工作就是測試。測試一個象uC/OS II一樣的多任務實時內核並不復雜,甚至可以在沒有應用程序的情況下測試。換句話說,就是讓這個實時內核在目標板上跑起來,讓內核自己測試自己。這樣做有兩個好處:第一,避免使本來就復雜的事情更加復雜;第二,如果出現問題,可以知道問題出在內核代碼上而不是應用程序。剛開始的時候可以運行一些簡單的任務和時鍾節拍中斷服務常式。一旦多任務調度成功地運行了,再添加應用程序的任務就是非常簡單的工作了。
5 結束語
採用基於ARM9的S3C2410嵌入式微處理器,可以使系統具備高性能的運算能力的同時便於與各種外設連接擴展,簡化了硬體設計,維持小型化的同時降低了系統成本。uC/OS II作為一個源代碼公開的操作系統,在具體應用中穩定可靠,並且支持uIP TCP/IP協議棧、ucGUI等,可擴展性強,功能強大。本系統采ARM9+uC/OS II開發設計,具有精度高、運行穩定、實時性好、抗干擾能力強、性價比高的特點,可以在各種工業場合中廣泛應用,達到了設計的初衷。
⑥ 編譯器是什麼
一個現代編譯器的主要工作流程如下:源代碼(sourcecode)→預處理器(preprocessor)→編譯器(compiler)→匯編程序(assembler)→目標代碼(objectcode)→連接器(Linker)→可執行程序(executables)編譯語言與解釋語言對比:許多人將高級程序語言分為兩類:編譯型語言和解釋型語言。然而,實際上,這些語言中的大多數既可用編譯型實現也可用解釋型實現,分類實際上反映的是那種語言常見的實現方式。(但是,某些解釋型語言,很難用編譯型實現。比如那些允許在線代碼更改的解釋型語言。)編譯器是一種特殊的程序,它可以把以特定編程語言寫成的程序變為機器可以運行的機器碼。把一個程序寫好,這時利用的環境是文本編輯器。這時我程序把程序稱為源程序。在此以後程序員可以運行相應的編譯器,通過指定需要編譯的文件的名稱就可以把相應的源文件(通過一個復雜的過程)轉化為機器碼了。
⑦ 編譯器的代碼分析
編譯器分析(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-threadedcode)。
機器代碼的生成是優化變型後的中間代碼轉換成機器指令的過程。現代編譯器主要採用生成匯編代碼(assembly code)的策略,而不直接生成二進制的目標代碼(binary object code)。即使在代碼生成階段,高級編譯器仍然要做很多分析,優化,變形的工作。例如如何分配寄存器(register allocatioin),如何選擇合適的機器指令(instruction selection),如何合並幾句代碼成一句等等。
⑧ 推薦幾個C++的編譯器
visual c++ 功能強大,不過需要的容量也很大 ,
TC2.0也不錯 很適合初學者 不過不是很標准 下面有它們的下載網站 你自己根據自己的情況,自己選擇吧,我的建議是VC6.0
TC2.0的:
http://218.64.170.103/dload1.html?cid=
http://218.64.170.103/dload1.html?cid=
VC6.0 的:
http://218.64.170.103/dload1.html?cid=
http://218.64.170.103/dload1.html?cid=
⑨ eclipse ds-5 用gcc編譯器編譯純匯編代碼時出現undefined reference to "main"錯誤
1. 鏈接時缺失了相關目標文件(.o)
2. 鏈接時缺少相關的庫文件(.a/.so)
3. 鏈接的庫文件中又使用了另一個庫文件
4 多個庫文件鏈接順序問題
⑩ 哪兩種編程語言需要使用編譯器將程序轉換為可執行代碼
基本上所有編程語言都需要編譯器
來將代碼轉換為機器碼(一堆0和1)
這樣我們才能讓cpu執行
最具代表性的我個人認為是匯編語言