久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久


嵌入式Linux編譯器GCC編譯流程

分享到:
           

    作(zuo)為自由軟件的(de)(de)旗艦(jian)項目,Richard Stallman在十多年(nian)前剛(gang)開始寫作(zuo)GCC的(de)(de)時候(hou),還只是僅(jin)僅(jin)把它(ta)當作(zuo)一個C程序語言的(de)(de)編譯器,GCC的(de)(de)意思也(ye)只是GNU C Compiler而已(yi)。

    經過(guo)了這么多年的發展,嵌(qian)入式Linux編(bian)(bian)譯器(qi)GCC已經不(bu)(bu)僅僅能(neng)支持(chi)(chi)C語(yu)(yu)言(yan)(yan),它現在還支持(chi)(chi)Ada語(yu)(yu)言(yan)(yan)、C++語(yu)(yu)言(yan)(yan)、Java語(yu)(yu)言(yan)(yan)、Objective C語(yu)(yu)言(yan)(yan)、PASCAL語(yu)(yu)言(yan)(yan)、COBOL語(yu)(yu)言(yan)(yan),并支持(chi)(chi)函數式編(bian)(bian)程和邏輯編(bian)(bian)程的Mercury語(yu)(yu)言(yan)(yan)等(deng)。而GCC也不(bu)(bu)再單指GNU C語(yu)(yu)言(yan)(yan)編(bian)(bian)譯器(qi)的意思了,而是變成了GNU編(bian)(bian)譯器(qi)家族了。

    GCC的編譯(yi)流程分為了(le)4個(ge)步驟,分別如下。

    ·預處理(Pre-Processing)。
    ·編譯(Compiling)。
    ·匯編(Assembling)。
    ·鏈接(Linking)。

  ;  編譯器通過程(cheng)序的擴展(zhan)名(ming)可分(fen)辨(bian)編寫(xie)原始(shi)程(cheng)序碼所用(yong)的語(yu)言,由于不(bu)同(tong)的程(cheng)序所需要執行編譯的步驟是不(bu)同(tong)的,因此GCC根據不(bu)同(tong)的后綴名(ming)對它們進行分(fen)別處(chu)理(li),表1.1指出了不(bu)同(tong)后綴名(ming)的處(chu)理(li)方(fang)式。

GCC所支持后綴名解釋
表1.1
表1.1

    GCC使用的基本語法為:
    gcc [option | filename]

    這(zhe)里(li)的(de)(de)option是(shi)GCC使用時(shi)的(de)(de)一些選(xuan)項,通過指定(ding)不(bu)同的(de)(de)選(xuan)項GCC可以實現其強(qiang)大的(de)(de)功能。這(zhe)里(li)的(de)(de)filename則是(shi)GCC要編譯(yi)的(de)(de)文件,GCC會根(gen)據用戶(hu)所(suo)指定(ding)的(de)(de)編譯(yi)選(xuan)項以及(ji)所(suo)識別的(de)(de)文件后(hou)綴名來(lai)對編譯(yi)文件進行相(xiang)應的(de)(de)處理。

   ; 本節從編(bian)譯流程的角(jiao)度(du)講解(jie)GCC的常見使(shi)用(yong)方法。

    首先,這里有一段簡(jian)單的C語(yu)言程(cheng)序,該程(cheng)序由兩個文件(jian)組成,其中“hello.h”為(wei)頭文件(jian),在“hello.c”中包含了“hello.h”,其源文件(jian)如下所示。

    /*hello.h*/
    #ifndef _HELLO_H_
    #define _HELLO_H_
    typedef unsigned long val32_t;
    #endif
    /*hello.c*/
    #include < stdio.h>
    #include < stdlib.h>
    #include "hello.h"
    int main()
    {
        val32_t i = 5;
        printf("hello, embedded world %d\n",i);
    }

    1.預處理階段

    GCC的選項“-E”可以使編譯器在預處理結束時就停止編譯,選項“-o”是指定GCC輸出的結果,其命令格式為如下所示。
     gcc –E –o [目標(biao)文(wen)件] [編譯文(wen)件]

    表2.6指出后綴名為“.i”的文件是經過預處理的C原始程序。要注意,“hello.h”文件是不能進行編譯的,因此,使編譯器在預處理后停止的命令如下所示。
  ;  [root@localhost gcc]# gcc –E –o hello.i hello.c

    在此處,選項“-o”是指目標文件,由表2.6可知,“.i”文件為已經過預處理的C原始程序。以下列出了hello.i文件的部分內容。
    # 2 "hello.c" 2
    # 1 "hello.h" 1
    typedef unsigned long val32_t;
    # 3 "hello.c" 2
    int main()
    {
        val32_t i = 5;
        printf("hello, embedded world %d\n",i);
    }

    由(you)此可見,GCC確實進行了(le)預處理,它把“hello.h”的(de)內(nei)容插入到hello.i文件中(zhong)了(le)。

    2.編譯階段

    編譯器在預處理結束之后,GCC首先要檢查代碼的規范性、是否有語法錯誤等,以確定代碼的實際要做的工作,在檢查無誤后,就開始把代碼翻譯成匯編語言,GCC的選項“-S”能使編譯器在進行完匯編之前就停止。由表1.1可知,“.s”是匯編語言原始程序,因此,此處的目標文件就可設為“.s”類型。
    [root@localhost gcc]# gcc –S –o hello.s hello.i

 &nbsp;  以(yi)下(xia)列出了hello.s的(de)內容,可見GCC已經將其轉(zhuan)化為匯編(bian)了,感興趣的(de)讀者(zhe)可以(yi)分析(xi)一下(xia)這(zhe)一行簡單的(de)C語言小程(cheng)序用匯編(bian)代碼是如(ru)何實現的(de)。

     .file "hello.c"
    .section .rodata
    .LC0:
    .string "hello, embedded world %d\n"
    .text
    .globl main
    .type main, @function
    main:
        pushl    %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        addl    $15, %eax
        addl    $15, %eax
        shrl    $4, %eax
        sall    $4, %eax
        subl    %eax, %esp
        movl    $5, -4(%ebp)
        subl    $8, %esp
        pushl    -4(%ebp)
        pushl    $.LC0
        call    printf
        addl    $16, %esp
        leave
        ret
        .size main, .-main
        .section .note.GNU-stack,"",@progbits
        . .ident "GCC: (GNU) 4.0.0 20050519 (Red Hat 4.0.0-8)"

    可以看(kan)到(dao),這(zhe)一小段C語(yu)言(yan)的(de)程序(xu)在(zai)匯編(bian)中已經復(fu)雜很多了(le),這(zhe)也是(shi)C語(yu)言(yan)作為中級語(yu)言(yan)的(de)優勢所在(zai)。

    3.匯編階段

    匯編階段是把編譯階段生成的“.s”文件生成目標文件,讀者在此使用選項“-c”就可看到匯編代碼已轉化為“.o”的二進制目標代碼了,如下所示。
    [root@localhost gcc]# gcc –c hello.s –o hello.o

    4.鏈接階段

   &nbsp;在成功編譯(yi)之(zhi)后,就進入了(le)鏈接階段。在這里(li)涉(she)及一個重要的概念——函數(shu)庫(ku)。

    在(zai)這個程(cheng)序(xu)中并沒(mei)有定義“printf”的(de)函數(shu)實現(xian),在(zai)預(yu)編譯中包(bao)含進的(de)“stdio.h”中也只有該函數(shu)的(de)聲明(ming),而沒(mei)有定義函數(shu)的(de)實現(xian),那么,是(shi)在(zai)哪里實現(xian)“printf”函數(shu)的(de)呢?

    后的答案是:系(xi)統(tong)把這些函數(shu)實現都(dou)已經被(bei)放入名(ming)為libc.so.6的庫文件中(zhong)去(qu)了(le),在(zai)沒有特別(bie)指定時,GCC會到(dao)系(xi)統(tong)默認的搜(sou)索路(lu)徑“/usr/lib”下(xia)進行(xing)查(cha)找,也就(jiu)是鏈(lian)接(jie)到(dao)libc.so.6庫函數(shu)中(zhong)去(qu),這樣就(jiu)能(neng)實現函數(shu)“printf”了(le),而這也就(jiu)是鏈(lian)接(jie)的作用。

    完成了鏈接之后,GCC就可以生成可執行文件,其命令如下所示。
    [root@localhost gcc]# gcc hello.o –o hello

    運行該可執行文件,出現正確的結果。
    [root@localhost gcc]# ./hello
   ; hello, embedded world 5


   熱點鏈接(jie):

   1、WindowsAndroid:在PC上運行Android
   2、ARM處理器是什么
   3、FPGA從事的工作是什么
   4、北京嵌入式培訓哪好
   5、嵌入式培訓資料:搭建交叉編譯環境

更多新聞>>