當前位置:首頁 » 編程軟體 » c編譯器結構圖

c編譯器結構圖

發布時間: 2024-06-30 13:34:39

1. c語言文件的編譯與執行的四個階段並分別描述

開發C程序有四個步驟:編輯、編譯、連接和運行。

任何一個體系結構處理器上都可以使用C語言程序,只要該體系結構處理器有相應的C語言編譯器和庫,那麼C源代碼就可以編譯並連接到目標二進制文件上運行。

1、預處理:導入源程序並保存(C文件)。

2、編譯:將源程序轉換為目標文件(Obj文件)。

3、鏈接:將目標文件生成為可執行文件(EXE文件)。

4、運行:執行,獲取運行結果的EXE文件。

(1)c編譯器結構圖擴展閱讀:

將C語言代碼分為程序的幾個階段:

1、首先,源代碼文件測試。以及相關的頭文件,比如stdio。H、由預處理器CPP預處理為.I文件。預編譯的。文件不包含任何宏定義,因為所有宏都已展開,並且包含的文件已插入。我歸檔。

2、編譯過程是對預處理文件進行詞法分析、語法分析、語義分析和優化,生成相應的匯編代碼文件。這個過程往往是整個程序的核心部分,也是最復雜的部分之一。

3、匯編程序不直接輸出可執行文件,而是輸出目標文件。匯編程序可以調用LD來生成可以運行的可執行程序。也就是說,您需要鏈接大量的文件才能獲得「a.out」,即最終的可執行文件。

4、在鏈接過程中,需要重新調整其他目標文件中定義的函數調用指令,而其他目標文件中定義的變數也存在同樣的問題。

2. c++中什麼是源程序什麼是編譯程序C語言的源程序結構是怎麼樣的

源程序是用c語言編寫的程序,編譯程序是軟體編譯後產生的二進制的數據

3. C語言代碼組成 - BSS、Data、Stack、Heap、Code、Const

一段C語言經過編譯連接後,成為一段可以運行的代碼,可運行的代碼可以分為以下四個部分組成:全局變數/靜態變數區、堆、棧、代碼區。其中全局變數/靜態變數區又分為未初始化變數區和初始化變數區,代碼區又分為代碼和常量區。即匯總下來,代碼可以分為6部分組成,包括:BSS區(未初始化的全局變數/靜態變數區)、Data區(實始化的全局變數區)、Stack區(棧區)、heap區(堆區)、Code區(代碼區)、const區(常量區)。

一、BSS區和Data區

C語言編程中定義的全局變數、靜態局部變數,就是分配在全局變數/靜態變數區域,但是為什麼又要分為BSS區域和Data區域呢?其實我們在定義全局或者靜態變數區,有時我會對它賦初始值,有的又不會賦初始化,比如我們定義的全局變數,初始化的賦值,是怎麼樣寫到變數區域中的,我們定義的靜態局部變數,在定義時初始化後,為什麼後面函數被調用,又不會再初始化呢?這個局部靜態變數是怎麼樣實始化的,什麼時候初始化的?

如果分析編譯後的匯編代碼,就會發現在代碼運行起來後,會有一段給變數賦值的指令,這一段代碼,不是我們C代碼對應的匯編,而是C編譯器生成的匯編譯代碼,這段代碼的作用就是給初始化了的靜態變數和全局變數進行初始化。這也是為什麼全局/靜態變數區域,要分BSS和Data的原因。

二、Stack區

棧是一種先進後出的數據結構,這種數據結構正好完美的匹配函數調用時的模型過程,比如函數f(a)在運行過程中調用函數f(b),f(a)在運行過程中的變數就是分配在棧中,通過在調用f(b)前,會將代碼中用到的R0~Rn寄存器的值保存到棧中,同時將函數的傳入參數寫入到棧中,然後進入f(b)函數,函數f(b)的變數b分配在棧中,當函數運行完畢後,釋放變數b,將棧中存放的f(a)函數的運行的R0~Rn寄存器值恢復到寄存器中,同時f(b)的返回結果存入到棧中,這樣f(a)繼續運行。當一個函數運行完畢後,它在棧中分配的臨時變數會全部釋放。

對於中斷也是一樣的,中斷發生時,也是一個函數打斷了另一個函數的運行,這種現場的保存(即寄存器的值),都是通過棧來完成的。所以棧的作用有:

三、Heap區

全局變數分配的內存在代碼整個運行周期內都是有效的,而在棧區分配的內存在函數調用完成後,就會釋放。這兩種內存模型都是由編譯器決定它的使用,代碼是無法控制的。那有沒有內存是由用戶控制的,要用時,就自由分配,不用時,就自行釋放?答案是肯定的,這部分內存就是堆。

用戶需要使用的動態內存,就是通過malloc函數,調用分配的,在沒有釋放前,可一直由代碼使用。當這部分內存不再需要使用時,可以通過free函數進行釋放,將它歸還到堆中。從這中可以看出,堆的內存,是按需分配的。這就是賦予了代碼很大的自由度,但這也是會帶來負作用的,比如:內存碎片化導致的malloc失敗;忘記釋放內存導致的內存泄露,而這些往往是致命的失誤。

四、Code區

代碼區就是編譯後機器指令,這些指令決定了功能的執行。我們編譯的代碼一般是下載進flash中,但是運行,卻有兩種方式:在RAM中運行和在ROM中運行。 在RAM中運行,即是boot啟動後,將flash中的代碼復制到RAM中,然後PC指針在指到RAM中的代碼中開始運行。 有時在調試時,我們可以直接將代碼下載進RAM中運行進行調試,這樣加快調試速度。便是大部分的情況我們的代碼是從flash中開始運行的。

五、常量區

代碼中的常量,一部分是作為立即數,在代碼區中,但是像定義的字元串、給某數組賦值的一串數值,這些常量,就存在常量區,我們常用const來定義一個常量,即該變數不能再必變。這部分的變數,編譯器一般將它定義的flash中。

六、各個區域大小的是如何決定的:

code區和const區:是由代碼的大小和代碼中常量的多少來決定的。

bss區和data區:這是由代碼中定義的全局變數和局部變數的多少來決定的。

stack區:這個可以由使用都自行定義大小,但使用都要根據自已代碼的情況,評估出一個合理的值,再定義其大小,如果定義的太小,很容易爆棧,導至代碼異常,但是如果定義的太大,就容易浪費內存。

heap區:RAM剩下的部分,編譯器就會作為堆區使用。

七、嵌入式代碼一般啟動過程

以STM32為例,通過分析其匯編啟支代碼,大致可以分為以下幾個步驟:

如果大家想看編譯扣,代碼文件的組成,可以查看統後生的map文件,裡面有詳細的數據,包括各個函數的分配內存,BSS,Data,Stack,Heap,Text的分配情況。

如果相要了解詳細的代碼啟動過程,可看它的啟動匯編文件。

4. 常見的C語言編譯器是什麼

目前最流行的C語言編譯器有以下幾種:

1、GNU Compiler Collection 或稱GCC

GCC(GNU Compiler Collection,GNU編譯器套件),是由 GNU 開發的編程語言編譯器。它是以GPL許可證所發行的自由軟體,也是 GNU計劃的關鍵部分。

GCC原本作為GNU操作系統的官方編譯器,現已被大多數類Unix操作系統(如Linux、BSD、Mac OS X等)採納為標準的編譯器,GCC同樣適用於微軟的Windows。GCC是自由軟體過程發展中的著名例子,由自由軟體基金會以GPL協議發布。

2、Microsoft C 或稱 MS C

Microsoft C 是c語言的一種IDE(集成開發環境),常見的還有Microsoft Visual C++,Borland C++,Watcom C++ ,Borland C++ ,Borland C++ Builder,Borland C++ 3.1 for DOS,Watcom C++ 11.0 for DOS,GNU DJGPP C++ ,Lccwin32 C Compiler 3.1,High C,Turbo C等等......

3、Borland Turbo C 或稱 Turbo C

Turbo C是美國Borland公司的產品,Borland公司是一家專門從事軟體開發、研製的大公司。該公司相繼推出了一套 Turbo系列軟體, 如Turbo BASIC, Turbo Pascal, Turbo Prolog, 這些軟體很受用戶歡迎。

(4)c編譯器結構圖擴展閱讀:

C編譯的整個過程很復雜,大致可以分為以下四個階段:

1、預處理階段在該階段主要完成對源代碼的預處理工作,主要包括對宏定義指令,頭文件包含指令,預定義指令和特殊字元的處理,如對宏定義的替換以及文件頭中所包含的文件中預定義代碼的替換等,總之這步主要完成一些替換工作,輸出是同源文件含義相同但內容不同的文件。

2、編譯、優化階段編譯就是將第一階段處理得到的文件通過詞法語法分析等轉換為匯編語言。優化包括對中間代碼的優化,如刪除公共表達式,循環優化等;和對目標代碼的生成進行的優化,如如何充分利用機器的寄存器存放有關變數的值,以減少內存訪問次數。

3、匯編階段將匯編語言翻譯成機器指令。

4、鏈接階段鏈接階段的主要工作是將有關的目標文件連接起來,即將在一個文件中引用的符號同該符號在另外一個文件中的定義連接起來,使得所有的目標文件成為一個能夠被操作系統裝入執行的統一整體。

5. 適合win10系統的c語言編譯器

桌面操作系統

對於當前主流桌面操作系統而言,可使用 VisualC++、GCC以及 LLVM Clang 這三大編譯器。

Visual C++(簡稱 MSVC)只能用於 Windows 操作系統;GCC 和 LLVM Clang除了可用於Windows操作系統之外,主要用於 Unix/Linux操作系統。

像現在很多版本的 Linux 都默認使用 GCC 作為C語言編譯器,而像 FreeBSD、macOS 等系統默認使用 LLVM Clang 編譯器。由於當前 LLVM 項目主要在 Apple 的主推下發展的,所以在 macOS中,Clang 編譯器又被稱為 Apple LLVM 編譯器。

MSVC 編譯器主要用於 Windows 操作系統平台下的應用程序開發,它不開源。用戶可以使用 Visual Studio Community 版本來免費使用它,但是如果要把通過 Visual Studio Community 工具生成出來的應用進行商用,那麼就得好好閱讀一下微軟的許可證和說明書了。

而使用 GCC 與 Clang 編譯器構建出來的應用一般沒有任何限制,程序員可以將應用程序隨意發布和進行商用。

MSVC 編譯器對 C99 標準的支持就十分有限,加之它壓根不支持任何 C11 標准,所以本教程中設計 C11 的代碼例子不會針對 MSVC 進行描述。所幸的是,Visual Studio Community 2017 加入了對 Clang 編譯器的支持,官方稱之為——Clang with Microsoft CodeGen,當前版本基於的是 Clang 3.8。

也就是說,應用於 Visual Studio 集成開發環境中的 Clang 編譯器前端可支持 Clang 編譯器的所有語法特性,而後端生成的代碼則與 MSVC 效果一樣,包括像 long 整數類型在 64 位編譯模式下長度仍然為 4 個位元組,所以各位使用的時候也需要注意。

為了方便描述,本教程後面涉及 Visual Studio 集成開發環境下的 Clang 編譯器簡稱為 VS-Clang 編譯器。

嵌入式系統

而在嵌入式系統方面,可用的C語言編譯器就非常豐富了,比如:

  • 用於 Keil 公司 51 系列單片機的 Keil C51 編譯器;

  • 當前大紅大紫的 Arino 板搭載的開發套件,可用針對 AVR 微控制器的 AVRGCC 編譯器;

  • ARM 自己出的 ADS(ARM Development Suite)、RVDS(RealView Development Suite)和當前最新的 DS-5 Studio;

  • DSP 設計商 TI(Texas Instruments)的 CCS(Code Composer Studio);

  • DSP 設計商 ADI(Analog Devices,Inc.)的 Visual DSP++ 編譯器,等等。


  • 通常,用於嵌入式系統開發的編譯工具鏈都沒有免費版本,而且一般需要通過國內代理進行購買。所以,這對於個人開發者或者嵌入式系統愛好者而言是一道不低的門檻。


  • 不過 Arino 的開發套件是可免費下載使用的,並且用它做開發板連接調試也十分簡單。Arino 所採用的C編譯器是基於 GCC 的。


  • 還有像樹莓派(Raspberry Pi)這種迷你電腦可以直接使用 GCC 和 Clang 編譯器。此外,還有像 nVidia 公司推出的 Jetson TK 系列開發板也可直接使用 GCC 和 Clang 編譯器。樹莓派與 Jetson TK 都默認安裝了 Linux 操作系統。


  • 在嵌入式領域,一般比較低端的單片機,比如 8 位的 MCU 所對應的C編譯器可能只支持 C90 標准,有些甚至連 C90 標準的很多特性都不支持。因為它們一方面內存小,ROM 的容量也小;另一方面,本身處理器機能就十分有限,有些甚至無法支持函數指針,因為處理器本身不包含通過寄存器做間接過程調用的指令。


  • 而像 32 位處理器或 DSP,一般都至少能支持 C99 標准,它們本身的性能也十分強大。而像 ARM 出的 RVDS 編譯器甚至可用 GNU 語法擴展。


  • 下圖展示了上述C語言編譯器的分類。


熱點內容
代號治癒如何創建伺服器 發布:2024-11-07 16:50:25 瀏覽:45
dos強制刪除文件夾 發布:2024-11-07 16:41:05 瀏覽:294
java協程框架 發布:2024-11-07 16:30:55 瀏覽:380
預測擬合演算法 發布:2024-11-07 16:30:45 瀏覽:663
橙光原始密碼是多少 發布:2024-11-07 16:24:33 瀏覽:34
安卓電話密碼是什麼 發布:2024-11-07 16:14:44 瀏覽:317
戰網客戶端文件夾 發布:2024-11-07 16:02:42 瀏覽:123
我的世界伺服器轉賬點券的指令 發布:2024-11-07 15:57:34 瀏覽:268
馬桶解壓 發布:2024-11-07 15:57:32 瀏覽:890
手機游戲蘋果和安卓哪個好 發布:2024-11-07 15:55:36 瀏覽:701