1. 程式人生 > >LCC編譯器的源程序分析 1 C編譯器的目標

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

pan 輸出 sub world www. 多目標 all ear push

先從簡單的目標來分析這個大規模的C編譯器,畢竟它的功能比較復雜,並且源程序的行數也是非常多的。因此,把簡單的目標定出來,然後再分析它,這樣才會有的放矢。接著再跟著編譯運行的主線來分析它的源程序。下面先看一下簡單的C例子,如下: #001 #include <stdio.h> #002 #003 int main(void) #004 { #005 int nTest1 = 1; #006 int nTest2 = 2; #007 int nTest3; #008 int i; #009 #010 nTest3 = nTest1 + nTest2; #011 printf("nTest3 = %d/r/n",nTest3);
#012 #013 for (i = 0; i < 5; i++) #014 { #015 printf("%d/r/n",nTest3+i); #016 } #017 #018 printf(__TIME__" "__DATE__"/r/nhello world/n"); #019 return 0; #020 } #021 上面的程序就是用來說明編譯器工作的例子,它在第一行裏包含了頭文件stdio.h,由於後面調用printf函數輸出顯示到屏幕裏。第二行空行,第三行是main函數,它是C程序的入口函數。在main函數裏,定義了幾個局部變量,分別第5678行的變量。第10行作兩個變量
nTest1nTest2的加法,然後賦值給變量nTest3。第11行顯示變量nTest3的值,是用10進制輸出顯示。在第1316行是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編譯器,在這裏主要介紹生成X86NASM匯編的代碼。上面的匯編代碼就是NASM的匯編格式,可以使用NASM編譯生成目標文件,然後再用連接程序生成可執行文件。如果不能看懂上面的NASM匯編,就需要去看NASM手冊了,這個手冊在網上有下載。如果想更深入理解匯編生成機器碼的過程,當然也可以深入分析NASM的程序實現。 從上面的C和匯編也可以看出,匯編代碼比C代碼要復雜,行數也比較多,還分了數據段和代碼段。所以使用C編譯器是可以大大地提高生產效率的,並且更容易理解,這樣就容易降低軟件的成本,容易開發大規模的軟件工程。

再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://www.cnblogs.com/captainbed

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