C程序阅读工具(Linux)
Vim集成Ctags/Taglist/Cscope/Winmanager/NERDTree/OmniCppComplete
Link:http://blog.sina.com.cn/s/blog_85882089010183gr.html
C程序Debug工具(Linux)
GDB
Link:http://www.open-open.com/lib/view/open1389251549477.html
C程序编译过程
一般高级语言程序编译的过程:预处理、编译、汇编、链接。
先写一个hello.c
#include <stdio.h> int main(){ printf("Hello, World!\n"); return 0; }
(1)预处理阶段:使用-E选项,对输入文件只做预处理不编译。当使用这个选项时,预处理器的输出被送到标准输出而不是存储到文件。如果想将预处理的输出存储到文件,可结合-o选项使用,使用如下:
1
2
3
4
5
|
[root@localhost c]
# ls
hello.c
[root@localhost c]
# gcc -E hello.c -o hello.i
[root@localhost c]
# ls
hello.c hello.i
|
使用less查看下hello.i:
1
|
[root@localhost c]
# less hello.i
|
(2)编译阶段:使用-S选项,将C程序编译为汇编语言文件后停止编译,gcc编译产生汇编文件的默认后缀为.s。
1
2
3
4
5
|
[root@localhost c]
# ls
hello.c hello.i
[root@localhost c]
# gcc -S hello.c
[root@localhost c]
# ls
hello.c hello.i hello.s
|
在gcc -S hello.c处,使用C源文件编译,也可以用gcc -S hello.i的预处理文件编译,结果一样。
使用-S编译时,也可以和-o结合使用指定编译产生的汇编语言文件的名字:
1
2
3
4
5
|
[root@localhost c]
# ls
hello.c hello.i hello.s
[root@localhost c]
# gcc -S hello.i -o hello_s.s
[root@localhost c]
# ls
hello.c hello.i hello.s hello_s.s
|
可使用less命令查看汇编代码。
(3)汇编阶段:使用-c选项,将C源文件或者汇编语言文件编译成可重定向的目标文件(二进制形式),其默认后缀为.o。
1
2
3
4
5
|
[root@localhost c]
# ls
hello.c hello.i hello.s hello_s.s
[root@localhost c]
# gcc -c hello.s
[root@localhost c]
# ls
hello.c hello.i hello.o hello.s hello_s.s
|
也可以和-o结合使用指定编译产生的目标文件的名字:
1
|
[root@localhost c]
# gcc -c hello.s -o hello.o
|
由于hello.o是二进制文件,使用less查看显示为乱码;
然后使用vim hello.o打开也显示为乱码,按下":%!xxd"查看其16进制形式,按下":%!xxd -r"退出 16进制查看模式,回到乱码状态。在退出vim时,若提示已经修改了文件,则使用":q!"强制退出。
(4)链接阶段:链接器将可重定向的目标文件hello.o以及库文件(如printf.o)执行并入操作,形成最终可执行的可执行目标文件。
[root@localhost c]
# ls
hello.c hello.i hello.o hello.s hello_s.s
[root@localhost c]
# gcc hello.o
[root@localhost c]
# ls
a.out hello.c hello.i hello.o hello.s hello_s.s
可使用-o选项,指定输出文件(即可执行目标文件)的名字:
1
2
3
|
[root@localhost c]
# gcc hello.o -o hello
[root@localhost c]
# ls
a.out hello hello.c hello.i hello.o hello.s hello_s.s
|
(5)执行阶段:
1
2
3
4
|
[root@localhost c]
# ./a.out
Hello, World!
[root@localhost c]
# ./hello
Hello, World!
|
由此,看出前面使用的gcc hello.c -o hello命令,将hello.c直接编译为可执行的目标文件,中间经过于处理器的预处理阶段(源文件到预处理文件),编译器的编译阶段(预处理文件到汇编文件),汇编器的汇编阶段(汇编文件到可重定向的目标文件),链接器的链接阶段(可重定向的目标文件到可执行的目标文件)。
还有其他的选项如下:
-Idir:dir是头文件所在的目录
-Ldir:dir是库文件所在的目录
-Wall:打印所有的警告信息
-Wl,options:options是传递给链接器的选项
编译优化选项:-O和-O2
-O选项告诉GCC 对源代码进行基本优化。这些优化在大多数情况下都会使程序执行的更快。-O2选项告诉GCC产生尽可能小和尽可能快的代码。
-O2选项将使编译的速度比使用-O时慢。但通常产生的代码执行速度会更快。
除了-O和-O2优化选项外,还有一些低级选项用于产生更快的代码。这些选项非常的特殊,而且最好只有当你完全理解这些选项将会对编译后的代码产生什么样的效果时再去使用。这些选项的详细描述,请参考GCC的联机帮助,在命令行上键入"man gcc"即可。
调试选项:-g(使用详情见第3部分)
-g选项告诉GCC产生能被GNU调试器使用的调试信息以便调试你的程序。
即:在生成的目标文件中添加调试信息,所谓调试信息就是源代码和指令之间的对应关系,在gdb调试和objdump反汇编时要用到这些信息。
3.调试
虽然GCC提供了调试选项,但是本身不能用于调试。Linux 提供了一个名为gdb的GNU调试程序。