欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

XX的學習日記(嵌入式)三——編譯器背后的故事 - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設/小程序開發(fā)/軟件開發(fā)

知識

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產生價值,我們在追求其視覺表現(xiàn)的同時,更側重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!

您當前位置>首頁 » 新聞資訊 » 技術分享 >

XX的學習日記(嵌入式)三——編譯器背后的故事

發(fā)表時間:2020-10-19

發(fā)布人:葵宇科技

瀏覽次數(shù):47

編譯器背后的故事

  • 一、可執(zhí)行程序是如何被組裝的?
    • 1. 用 gcc 生成 .a 靜態(tài)庫和 .so 動態(tài)庫
      • 1.1 編輯得到舉例的程序:hello.h、hello.c和main.c
      • 1.2 將hello.c編譯成.o文件;
      • 1.3由.o文件創(chuàng)建靜態(tài)庫
      • 1.4 在程序中使用靜態(tài)庫
      • 1.5由.o文件創(chuàng)建動態(tài)庫文件
      • 1.6 在程序中使用動態(tài)庫
    • 2.Linux下靜態(tài)庫.a與.so庫文件的生成與使用
      • 2.1 編輯所需程序
      • 2.1 靜態(tài)庫.a文件的生成與使用
      • 2.2 共享庫.so文件的生成與使用
    • 3. 將第一次學習內容的程序進行改編
      • 3.1 完成目標(1)
      • 3.2 完成目標(2)
  • 二、Gcc不是一個人在戰(zhàn)斗。
    • 1. Linux GCC常用命令
      • 1.1 程序準備
      • 1.2 程序的簡單編譯
      • 1.3 程序的分步編譯
    • 2. 比較hello.asm與C代碼生成的可執(zhí)行文件
      • 2.1 搭建環(huán)境:在Ubuntu上安裝nasm

一、可執(zhí)行程序是如何被組裝的?

1. 用 gcc 生成 .a 靜態(tài)庫和 .so 動態(tài)庫

我們通常把一些公用函數(shù)制作成函數(shù)庫,供其它程序使用。函數(shù)庫分為靜態(tài)庫和動態(tài)庫兩種。靜態(tài)庫在程序編譯時會被連接到目標代碼中,程序運行時將不再需要該靜態(tài)庫。動態(tài)庫在程序編譯時并不會被連接到目標代碼中,而是在程序運行是才被載入,因此在程序運行時還需要動態(tài)庫存在。
我們通過舉例來說明在Linux中如何創(chuàng)建靜態(tài)庫和動態(tài)庫,以及使用它們,在創(chuàng)建函數(shù)庫前,我們先來準備舉例用的源程序,并將函數(shù)庫的源程序編譯成.o文件。

1.1 編輯得到舉例的程序:hello.h、hello.c和main.c

hello.c是函數(shù)庫的源程序,其中包含公用函數(shù)hello,該函數(shù)將在屏幕上輸出"Hello XXX!"。hello.h為該函數(shù)庫的頭文件。main.c為測試庫文件的主程序,在主程序中調用了公用函數(shù)hello。
hello.h
在這里插入圖片描述
hello.c
在這里插入圖片描述
main.c
在這里插入圖片描述

1.2 將hello.c編譯成.o文件;

無論靜態(tài)庫,還是動態(tài)庫,都是由.o文件創(chuàng)建的。因此,我們必須將源程序hello.c通過gcc先編譯成.o文件。
在系統(tǒng)提示符下鍵入以下命令得到hello.o文件。
gcc -c hello.c
通過ls命令查看是否生成了hello.o文件
在這里插入圖片描述

1.3由.o文件創(chuàng)建靜態(tài)庫

靜態(tài)庫文件名的命名規(guī)范是以lib為前綴,緊接著跟靜態(tài)庫名,擴展名為.a。例如:我們將創(chuàng)建的靜態(tài)庫名為myhello,則靜態(tài)庫文件名就是libmyhello.a。在創(chuàng)建和使用靜態(tài)庫時,需要注意這點。創(chuàng)建靜態(tài)庫用ar命令。
在系統(tǒng)提示符下鍵入以下命令將創(chuàng)建靜態(tài)庫文件libmyhello.a,并用ls命令查看結果
ar -crv libmyhello.a hello.o

在這里插入圖片描述

1.4 在程序中使用靜態(tài)庫

靜態(tài)庫制作完了,如何使用它內部的函數(shù)呢?只需要在使用到這些公用函數(shù)的源程序中包含這些公用函數(shù)的原型聲明,然后在用gcc命令生成目標文件時指明靜態(tài)庫名,gcc將會從靜態(tài)庫中將公用函數(shù)連接到目標文件中。注意,gcc會在靜態(tài)庫名前加上前綴lib,然后追加擴展名.a得到的靜態(tài)庫文件名來查找靜態(tài)庫文件。
在程序3:main.c中,我們包含了靜態(tài)庫的頭文件hello.h,然后在主程序main中直接調用公用函數(shù)hello。下面先生成目標程序hello,然后運行hello程序看看結果如何。
我們輸入以下指令:gcc main.c libmyhello.a -o hello
在這里插入圖片描述
我們刪除靜態(tài)庫文件試試公用函數(shù)hello是否真的連接到目標文件 hello中了。
在這里插入圖片描述
(這里我打錯了一段指令,馬了別介意: D)
程序照常運行,靜態(tài)庫中的公用函數(shù)已經連接到目標文件中了。

1.5由.o文件創(chuàng)建動態(tài)庫文件

我們繼續(xù)看看如何在Linux中創(chuàng)建動態(tài)庫。我們還是從.o文件開始。
動態(tài)庫文件名命名規(guī)范和靜態(tài)庫文件名命名規(guī)范類似,也是在動態(tài)庫名增加前綴lib,但其文件擴展名為.so。例如:我們將創(chuàng)建的動態(tài)庫名為myhello,則動態(tài)庫文件名就是libmyhello.so。用gcc來創(chuàng)建動態(tài)庫。
在系統(tǒng)提示符下鍵入以下命令得到動態(tài)庫文件libmyhello.so,并用ls命令查看
gcc -shared -fPIC -o libmyhello.so hello.o (-o不可少)
在這里插入圖片描述

1.6 在程序中使用動態(tài)庫

在程序中使用動態(tài)庫和使用靜態(tài)庫完全一樣,也是在使用到這些公用函數(shù)的源程序中包含這些公用函數(shù)的原型聲明,然后在用gcc命令生成目標文件時指明動態(tài)庫名進行編譯。我們先運行gcc命令生成目標文件,再運行它看看結果。
輸入以下指令:gcc -o hello main.c -L. -lmyhello
在這里插入圖片描述
這里出現(xiàn)了錯誤,我們看看錯誤提示,原來是找不到動態(tài)庫文件libmyhello.so。程序在運行時,會在/usr/lib和/lib等目錄中查找需要的動態(tài)庫文件。若找到,則載入動態(tài)庫,否則將提示類似上述錯誤而終止程序運行。我們將文件libmyhello.so復制到目錄/usr/lib中,再試試。
在這里插入圖片描述

2.Linux下靜態(tài)庫.a與.so庫文件的生成與使用

如前面一樣,我們先生成舉例所需要的文件

2.1 編輯所需程序

A1.c
在這里插入圖片描述
A2.c
在這里插入圖片描述

A.h
在這里插入圖片描述
test.c
在這里插入圖片描述

2.1 靜態(tài)庫.a文件的生成與使用

(1) 生成目標文件(XXX.o)
指令如下:gcc -c A1.c A2.c
在這里插入圖片描述
(2)生成靜態(tài)庫.a文件
指令如下:ar crv libafile.a A1.o A2.o
在這里插入圖片描述
(3)使用.a 庫文件,創(chuàng)建可執(zhí)行程序(若采用此種方式,需保證生成的.a 文件與.c 文件保存在同一目錄下,即都在當前目錄下)
指令如下:

cpp gcc -o test test.c libafile.a
./test

在這里插入圖片描述

2.2 共享庫.so文件的生成與使用

(1)生成目標文件(XXX.o)(此處生成.o 文件必須添加"-fpic"(小模式,代碼少),否則在生成.so文件時會出錯)
指令:gcc -c -fpic A1.c A2.c
(2)生成共享庫.so文件
指令:gcc -shared *.o -o libsofile.so
(3)使用.so 庫文件,創(chuàng)建可執(zhí)行程序
指令:gcc -o test test.c libsofile.s
在這里插入圖片描述
當輸入以下指令時:./test
發(fā)現(xiàn)出現(xiàn)錯誤:
在這里插入圖片描述
原因與之前使用動態(tài)庫的情況相同:找不到對用的.so文件,故需將對應 so 文件拷貝到對應路徑。
指令
如下:sudo cp libsofile.so /usr/lib
在這里插入圖片描述
同時可直接使用 gcc -o test test.c -L. -lname,來使用相應庫文件
其中,
-L.:表示在當前目錄下,可自行定義路徑 path,即使用-Lpath 即可。
-lname:name:即對應庫文件的名字(除開 lib),即若使用 libafile.a,則 name 為 afile;若要使用 libsofile.so,則 name 為 sofile。

3. 將第一次學習內容的程序進行改編

目標:
(1)除了x2x函數(shù)之外,再擴展寫一個x2y函數(shù)(功能自定),main函數(shù)代碼將調用x2x和x2y ;將這3個函數(shù)分別寫成單獨的3個 .c文件,并用gcc分別編譯為3個.o 目標文件;將x2x、x2y目標文件用 ar工具生成1個 .a 靜態(tài)庫文件, 然后用 gcc將 main函數(shù)的目標文件與此靜態(tài)庫文件進行鏈接,生成最終的可執(zhí)行程序,記錄文件的大小。
(2)將x2x、x2y目標文件用 ar工具生成1個 .so 動態(tài)庫文件, 然后用 gcc將 main函數(shù)的目標文件與此動態(tài)庫文件進行鏈接,生成最終的可執(zhí)行程序,記錄文件的大小,并與之前做對比。

3.1 完成目標(1)

(1)編輯所需程序
x2x.c
在這里插入圖片描述
x2y.c
在這里插入圖片描述
main.c
在這里插入圖片描述
(2)將以上文件用gcc編譯成.o文件
在這里插入圖片描述
在這里插入圖片描述
(3)將x2x.o和x2y.o用 ar工具生成 .a 靜態(tài)庫文件
在這里插入圖片描述
(4)使用gcc將main.c文件與此靜態(tài)庫文件進行鏈接
在這里插入圖片描述
(5) 運行xymain程序
在這里插入圖片描述
在這里插入圖片描述
記錄文件大小為16888B

3.2 完成目標(2)

(1)將x2x.o、x2y.o文件用ar工具生成.so 動態(tài)庫文件在這里插入圖片描述
(2)用gcc將main.c文件與此動態(tài)庫文件進行鏈接
在這里插入圖片描述
(3)運行somain
在這里插入圖片描述
記錄文件大小為16888B


二、Gcc不是一個人在戰(zhàn)斗。

GCC 的意思也只是 GNU C Compiler 而已。經過了這么多年的發(fā)展,GCC 已經不僅僅能支持 C語言;它現(xiàn)在還支持 Ada 語言、C++ 語言、Java 語言、Objective C 語言、Pascal 語言、COBOL語言,以及支持函數(shù)式編程和邏輯編程的 Mercury 語言,等等。而 GCC 也不再單只是 GNU C 語言編譯器的意思了,而是變成了 GNU Compiler Collection 也即是 GNU 編譯器家族的意思了。另一方面,說到 GCC 對于操作系統(tǒng)平臺及硬件平臺支持,概括起來就是一句話:無所不在。

1. Linux GCC常用命令

1.1 程序準備

在這里插入圖片描述

1.2 程序的簡單編譯

這個程序的一步到位的編譯指令是gcc test.c -o main
在這里插入圖片描述

1.3 程序的分步編譯

實質上,上述編譯過程是分為四個階段進行的,即預處理(也稱預編譯,Preprocessing)、編譯(Compilation)、匯編 (Assembly)和連接(Linking)。

gcc -E test.c -o test.i //預處理
gcc -S test.i -o test.s //編譯
gcc -c test.s -o test.o //匯編
gcc test.o -o test //連接

執(zhí)行以上指令后生成以下文件,并查看運行結果
在這里插入圖片描述

2. 比較hello.asm與C代碼生成的可執(zhí)行文件

2.1 搭建環(huán)境:在Ubuntu上安裝nasm

相關案例查看更多