分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!
先從簡單的目標來分析這個大規模的
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...