有关gcc,make,gdb的知识
GCC
編譯四階段:預處理 (展開頭文件) ??????????????gcc -E test.c -o test.i
編譯(語法檢查,將c編譯成匯編語言)gcc -S test.i -o test.s
匯編(將匯編語言變為二進制) gcc -c test.s -o test.o
鏈接(將頭文件與c庫鏈接) gcc test.o -o test
(./test 運行程序,查看結果是否正確)
注意:匯編時 -c 為小寫的c
1.預處理
由于在 test.c 中使用了頭文件 stdio.h,所以 GCC 在編譯時首先要把頭文件stdio.h 中的內容加載到 test.c 中的首部。
在 shell 中輸入命令“gcc -E test.c -o test.i”。其中,參數 E 告訴 gcc 命令只進行預編譯,不做其他處理;參數 o 用來指明輸出的文件名為 test.i。命令運行完畢后就會產生一個名為 test.i 的文件。
2.編譯 實現三個步驟。
?
步驟 1 稱為詞法分析,主要負責檢查關鍵字、標識符等是否正確。
步驟 2 稱為語法分析,主要負責檢查程序中語句的語法是否正確。
步驟 3 稱為語義分析,主要負責檢查程序中語句的邏輯意義是否正確。
3.匯編
匯編階段的任務是把匯編程序翻譯成 CPU 可以識別的二進制文件,該文件又稱為目標文件。
鏈接
目標文件雖然已經可以被 CPU 直接識別,但是單個目標文件一般是無法運行的。原因在于一個程序往往是由多個源文件組成的,每個源文件只對應一個目標文件。也許有人會問, test 程序不就只有一個源文件 test.c 嗎,為什么也不能直接運行呢?原因是 test.c 使用了 stdio.h 對應的庫函數,所以必須要把 test.o 文件和函數庫文件鏈接在一起才能運行。
?
?
?
Make
Vim hello.c (編寫簡單程序)
Vim Makefile (寫makefile 主要告訴make要做的事情)
代碼如下:
CC = gcc
Target = test
Object = test.o
$(target) : $(object)
$(CC) $(object) -o $(target)
.PHONY : clean 注:此句目的是將clean變為一個偽目標
防止make執行存在的文件clean。
Clean:
Rm -rf test *.o
注:target 為目標,通常是要產生的文件的名稱
Object 為依賴(dependency)指用來輸入從而產生目標的文件
Command 為命令 是make的執行動作,一個命令占一行,命令前第一個字符為TAB鍵。(上面$(CC)、rm 前均有Tab鍵)
Gdb
GNU 開發了 GDB 調試器(GNU Debugger)。GDB 的調試功能非常強大,甚至可以和 Visual C++、Visual Basic、Jbuilder 等開發工具的調試器相媲美。但 GDB 的缺點是沒
有圖形調試界面。
前期準備 vim add.c
代碼:
#include<stdio.h>
Int add(int i,int j)
{
Return(i+j);
}
Int main()
{
Int i=1,j=4,sum =0;
Sum=add(i,j);
Printf(“sum i %d”,sum);
return 0;
}
?
?
[root@localhost 0929]# gcc -g add.c -o add
[root@localhost 0929]# gdb add
GNU gdb Red Hat Linux (6.5-25.el5rh)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. ?Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
(可以看到,GDB?首先顯示了版本信息和庫信息。隨后?GDB?停留在符號“(gdb)”處等待用戶輸入調試命令。GDB 提供了大量的命令來實現各種調試功能,開始嘗試指令。)
?
(gdb) l
(在 GDB 中通過命令 l(list 的縮寫)可以查看所有的代碼行數。一次顯示十行)
1 ??????#include<stdio.h>
2
3 ??????int add(int i,int j)
4 ??????{
5 ??????return(i+j);
6 ??????}
7
8 ??????int main()
9 ??????{
10 ?????int a=1,b=4,sum=0;
(gdb) l
11 ?????sum=add(a,b);
12 ?????printf("sum is%d",sum);
13 ?????return 0;
14 ?????}
(gdb) r
?
(在 GDB 中通過命令 r(run 的縮寫)運行程序。GDB 默認從代碼的首行開始運行 (也可以通過“r 行數”的方式讓程序從指定行數開始運行)。如果程序中有斷點,則 程序會在斷點行數的前一行暫停運行))
?
Starting program: /home/0929/add
sum is5
Program exited normally.
(gdb) b 5
?
(斷點是調試程序的重要方法,通過斷點可以知道程序每一步的執行狀況(比如當前 變量的值、函數是否調用、堆棧使用情況等)。在 GDB 中通過命令 b(breakpoint 的縮寫)進行斷點設置。)
?
Breakpoint 1 at 0x8048387: file add.c, line 5.
(gdb) info b
?
(使用命令 b 可以設置多個斷點,所以用戶需要能夠隨時查看各個斷點的情況,在 GDB 中通過命令“info b”查看所有的斷點情況。)
?
Num Type ??????????Disp Enb Address ???What
1 ??breakpoint ????keep y ??0x08048387 in add at add.c:5
(gdb) r
Starting program: /home/0929/add
?
Breakpoint 1, add (i=1, j=4) at add.c:5
5 ??????return(i+j);
(gdb) c
?
(在 GDB 中通過命令 c 讓程序繼續往下運行。)
?
Continuing.
sum is5
Program exited normally.
?
(gdb) r
Starting program: /home/0929/add
?
Breakpoint 1, add (i=1, j=4) at add.c:5
5 ??????return(i+j);
(gdb) s
?
(在程序邏輯比較復雜的時候往往需要程序能一步一步的往下運行,但如果每行都設置一個斷點的話又會很麻煩。在 GDB 中可以通過命令 s(step 的縮寫)和 n(next 的縮寫)讓程序一步一步的往下運行。其中 s 可以在發生函數調用時進入函數內部運行,而 n 不會進入函數內部運行。)
?
6 ??????}
(gdb) s
main () at add.c:12
12 ?????printf("sum is%d",sum);
(gdb) s
13 ?????return 0;
(gdb) s
14 ?????}
(gdb) s
0x0032bdec in __libc_start_main () from /lib/libc.so.6
(gdb) s
Single stepping until exit from function __libc_start_main,
which has no line number information.
sum is5
Program exited normally.
(gdb) [root@localhost 0929]#
?
(快捷鍵ctrl+d,退出gdb界面)
?
[root@localhost 0929]#
?
?
總結
以上是生活随笔為你收集整理的有关gcc,make,gdb的知识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 嵌入式入门学习
- 下一篇: 文件管理,系统管理,系统安全常用指令整理