LCC編譯器的源程式分析 1 C編譯器的目標

2021-08-30 15:22:34 字數 3164 閱讀 3397

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!

先從簡單的目標來分析這個大規模的

c 編譯器,畢竟它的功能比較複雜,並且源程式的行數也是非常多的。因此,把簡單的目標定出來,然後再分析它,這樣才會有的放矢。接著再跟著編譯執行的主線來分析它的源程式。下面先看一下簡單的

c 例子,如下:

#001 #include

#002 

#003 int main(void)

#004 

#017  

#018  printf(__time__" "__date__"/r/nhello world/n");

#019  return 0;

#020 }

#021 

上面的程式就是用來說明編譯器工作的例子,它在第一行裡包含了標頭檔案

stdio.h

,由於後面呼叫

printf

函式輸出顯示到螢幕裡。第二行空行,

第三行是

main

函式,它是

c 程式的入口函式。在

main

函式裡,定義了幾個區域性變數,分別第

5 ,

6 ,

7 ,

8 行的變數。第

10行作兩個變數

ntest1

和 ntest2

的加法,然後賦值給變數

ntest3

。第11

行顯示變數

ntest3

的值,是用

10進製輸出顯示。在第

13到 16

行是5 次輸出

ntest3+i

值。在第

18行裡輸出編譯這個程式的時間和

hello world

的字串。 c

編譯器的任務,就是把上面的源程式變換到彙編**輸出,或者變成其它中間**輸出。在這裡

lcc編譯器是輸出彙編**的,所以就不介紹其它的中間**輸出。那麼

lcc把上面的源程式變成什麼樣的彙編輸出呢?下面就先把它的目標**看一下,如下:

#001 [global $main]

#002 [section .text]

#003 $main:

#004 push ebx

#005 push esi

#006 push edi

#007 push ebp

#008 mov ebp, esp

#009 sub esp, 16

#010 mov dword [ebp + -12], 1

#011 mov dword [ebp + -16], 2

#012 mov edi, dword [ebp + -12]

#013 mov esi, dword [ebp + -16]

#014 lea edi, [esi + edi]

#015 mov dword [ebp + -8], edi

#016 mov edi, dword [ebp + -8]

#017 push dword edi

#018 lea edi, [$l2]

#019 push dword edi

#020 call $printf

#021 add esp, 8

#022 mov dword [ebp + -4], 0

#023 $l3:

#024 mov edi, dword [ebp + -8]

#025 mov esi, dword [ebp + -4]

#026 lea edi, [esi + edi]

#027 push dword edi

#028 lea edi, [$l7]

#029 push dword edi

#030 call $printf

#031 add esp, 8

#032 $l4:

#033 inc dword [ebp + -4]

#034 cmp dword [ebp + -4], 5

#035 jl near $l3

#036 lea edi, [$l8]

#037 push dword edi

#038 call $printf

#039 add esp, 4

#040 mov eax, 0

#041 $l1:

#042 mov esp, ebp

#043 pop ebp

#044 pop edi

#045 pop esi

#046 pop ebx

#047 ret

#048 [extern $printf]

#049 [section .data]

#050 times ($-$$) & 0 nop

#051 $l8:

#052 db '00:30:28 apr 07 2007', 13, 10, 'hello world', 10, 0

#053 times ($-$$) & 0 nop

#054 $l7:

#055 db '%d', 13, 10, 0

#056 times ($-$$) & 0 nop

#057 $l2:

#058 db 'ntest3 = %d', 13, 10, 0

#059 

lcc是可以生成很多目標**的

c 編譯器,在這裡主要介紹生成

x86的 nasm

彙編的**。上面的彙編**就是

nasm

的彙編格式,可以使用

nasm

編譯生成目標檔案,然後再用連線程式生成可執行檔案。如果不能看懂上面的

nasm

彙編,就需要去看

nasm

nasm

的程式實現。

從上面的

c 和彙編也可以看出,彙編**比

c **要複雜,行數也比較多,還分了資料段和**段。所以使用

c 編譯器是可以大大地提高生產效率的,並且更容易理解,這樣就容易降低軟體的成本,容易開發大規模的軟體工程。

給我老師的人工智慧教程打call!

LCC編譯器的源程式分析 12 13

語法分析是比較複雜的處理,下面再來分析乙個例子,它的 如下 typedef unsigned short wchar t typedef wchar t wint t 第一句語句在lcc裡的處理,前面已經解釋清楚,主要生成wchar t儲存符號表裡,並且記錄這個id的型別屬性。那麼第二句是怎麼樣通過...

LCC編譯器的源程式分析 18 19

lcc編譯器的源程式分析 19 全域性函式的定義 函式定義funcdefn處理裡,已經準備好呼叫引數和引數返回,接著就是呼叫全域性函式宣告來處理。如下面的 132 宣告函式。133 cfunc dclglobal sclass,id,ty,pt 134 上面的 是處理函式全域性定義。現在就去就分析d...

LCC編譯器的源程式分析 20 復合語句

在 c語言裡,有一種語句叫做復合語句。它是由 把一些語句括起來的,如下面的例子 在lcc 裡處理這樣的復合語句的函式是 compound 它在上面函式定義函式 funcdefn 是這樣呼叫的 150labels table null,labels 151stmtlabs table null,lab...