第三章 編譯器基礎
看了這個題目,請不要誤會我要告訴您編譯器是怎麼實現的,我寫這節的主要目的是告訴您通常編譯器是怎樣對待您所寫的程式的。大家都知道,程式最終都要在cpu上執行,那麼像c語言這樣的高階語言來說,編譯器就是聯結c和cpu之間的橋梁了。在這一節裡我要告訴您編譯器是如何充當這個「橋梁」角色的。
本節首先講述一下程式設計師的層次問題,目的是讓我們自己知道需要成為一名什麼樣的程式設計師;然後分別是編譯器的相關介紹以及編譯器是如何「對待」程式等內容。
3.1 軟體和程式設計師的層次
如果要了解程式設計師的層次,那就要先看看程式的層次了。看圖3.1:
程式源**
編譯器
**處理器(cpu)
從上面的約定可以看出,不同的編譯器函式的呼叫約定細節是不一樣的,這也決定了不同呼叫約定的函式行為的不同。
cdecl呼叫約定由於由呼叫者負責堆疊的清除,因此可以實現可變引數的函式(如printf函式)。但是這樣也會增加程式的**空間,因為每乙個呼叫函式的地方都需要相關的堆疊處理**。
stdcall呼叫約定是windows作業系統api函式的預設呼叫方式,沒有進行什麼特別的處理。
fastcall呼叫約定相當於stdcall約定的優化版本,它通過兩個暫存器來實現引數的傳遞,這樣就減少了堆疊的處理,因此可以加快函式的執行。同理可以推理出,如果fastcall呼叫約定的函式引數個數小於或等於2個的話,會取得最快的執行速度。
arm編譯器的呼叫約定是使用4個暫存器來傳遞引數,因此對於arm平台的程式來說,在小於等於4個引數的情況下可以得到最優化的函式呼叫效率。對於空間較大的引數(如乙個大的結構體)arm編譯器將通過堆疊進行傳遞。
對於函式的返回值,如果需要的傳遞空間比較小則通過暫存器傳遞,如果需要的空間較大,則通過記憶體進行間接的傳遞。上述幾種方式的返回值傳遞都是一樣的。
3.8 開發中與執行時
我一直希望能夠將您從c語言的世界中引入程式執行的二進位制世界之中,並一直試圖將二者的內在聯絡展示給您。雖然我並不能準確地知道是否達到了目的,但是我還是想在這裡總結一下它們之間的關係。
c語言與二進位制分別對應了開發中與執行時兩個程式的過程概念。對於很多的初學者會問一些諸如cpu怎麼識別我定義的變數這類問題,回答這類問題是很棘手的。如果我告訴他cpu不認識我們定義的變數時,他一定會問cpu不認識那麼程式怎麼執行啊?這就像是乙個在迷宮裡的人,迷失在開發中與執行時兩個世界組成的迷宮裡。
變數是開發中的概念,經過編譯器的處理,會將變數的外衣去掉,送進赤裸裸二進位制資料的二進位制世界中。編譯器就是這兩個世界的橋梁。在二進位制世界裡,cpu只認識二進位制的資料和指令,沒有資料型別的概念。例如,對於開發過程中的乙個陣列,到了二進位制層面就變成了乙個固定大小的二進位制空間,不管這個資料型別是char的還是int的,cpu只是根據相應的操作指令來執行對這塊空間的操作。因此,對於在c語言中的諸如變數、函式、結構體以及陣列等等,統統是開發過程中的概念,只有編譯器會接受這些概念。到了執行的時候cpu一概不認,cpu就是乙個非常簡單的傢伙,只知道根據編譯器生成的二進位制指令執行,「只要符合規範,我就一言不發」。
只有透徹的理解了開發中與執行時之間的關係,才能從深層次理解程式的執行。因此在某種程度上來說,理解一下編譯器本身的「內幕」是很有必要的。只有二進位制世界,才是程式真正的世界。
3.9 小結
這一章中主要介紹了編譯器的分類以及編譯器在整個系統中的作用,同時也包含了一些程式執行的知識,在這裡著重說明了開發中和執行時兩個程式的階段,而編譯器則成為了這兩個階段的橋梁。通過編譯器對開發中的**進行編譯鏈結,才生成了可以執行的**。編譯器的作用就是將源**轉換成可以在目標機器上執行的機器碼,這樣可以通過高階語言的開發大大提高機器碼的開發速度,可以說編譯器是乙個提高開發效率的工具。
思考題編譯器將程式分成幾種型別的資料?不同型別之間的區別是什麼?
編譯原理 第三章
單詞的表示形式 用二元式來表示 單詞種別,單詞符號的屬性值 單詞符號的屬性 指單詞符號的特性或特徵。單詞符號的屬性值 反映單詞特性或特徵的值。4 狀態轉換圖法 1 狀態轉換圖 一張有限方向圖 2 狀態轉換圖的功能 識別 接受 一定的符號串 單詞 正規式與正規集 我們可以把具有相同特徵的字放在一起組成...
編譯原理 第三章
一,知識點 1.正規式與正規集的定義 遞迴的定義方法 1 和 是 上的正規式,它們所表示的正規集分別為和 2 任何a 是 上的乙個正規式,他所表示的正規集為 3 假定u和v都是 上的正規式,他們所表示的正規集分別記為l u 和l v 那麼 a u v 是正規式,所表示的正規集為l u l v b u...
第三章 UI開發
alertdialog可以在當前的介面彈出乙個對話方塊,這個對話方塊是置頂於所有介面元素之上的,能夠遮蔽掉其他控制項的互動能力,因此一般 alertdialog都是用於提示一些非常重要的內容或者警告資訊。public class mainactivity extends activity imple...