Linux C程序的预处理、编译、汇编、链接及运行过程
Linux C程序的预处理、编译、汇编、链接及运行过程
Hello Word 程序直接编译运行过程
在Linux系统下,任意目录内创建一个简单的C程序,命名为hello.c,其代码如下:
1 #include <stdio.h> 2 int main(){ 3 //这里有个注释 4 printf("Hello Word\n"); 5 return 0; 6 }
编译代码,生成可执行文件 a.out:
XXXX@ubuntu:~/hello$ gcc hello.c XXXX@ubuntu:~/hello$ ls a.out hello.c
运行可执行文件a.out ,生成结果:
XXXX@ubuntu:~/hello$ ./a.out Hello Word
以上是一个程序最简单、最快捷的编译运行方式,但是在实际上,程序从代码到机器可执行的过程中,涉及预处理、编译、汇编、链接及运行等过程,了解这些过程是十分有必要的。
预处理
对上面的程序hello.c进行预处理过程,通常会进行以下操作:
1、删除程序里的注释内容;
2、把头文件的内容复制到预处理指令位置。
对==.c==文件的预处理,可以采用下述方法:
XXXX@ubuntu:~/hello$ gcc -E hello.c -o hello.i XXXX@ubuntu:~/hello$ ls hello.c hello.i
说明:
1、gcc -E filename.c 表示对一个.c文件进行预处理,E必须大写
2、gcc -E filename.c -o filename.i 表示把预处理文件命名为filename.i,此处的 -o 必须小写
3、预处理文件用 filename.i来表示。
1 # 1 "<built-in>" 2 # 1 "<command-line>" 3 # 1 "/usr/include/stdc-predef.h" 1 3 4 4 # 1 "<command-line>" 2 5 # 1 "hello.c" 6 # 1 "/usr/include/stdio.h" 1 3 4 7 # 27 "/usr/include/stdio.h" 3 4 8 # 1 "/usr/include/features.h" 1 3 4 9 # 367 "/usr/include/features.h" 3 4 10 # 1 "/usr/include/i386-linux-gnu/sys/cdefs.h" 1 3 4 11 # 410 "/usr/include/i386-linux-gnu/sys/cdefs.h" 3 4 12 # 1 "/usr/include/i386-linux-gnu/bits/wordsize.h" 1 3 4 13 # 411 "/usr/include/i386-linux-gnu/sys/cdefs.h" 2 3 4 14 # 368 "/usr/include/features.h" 2 3 4 15 # 391 "/usr/include/features.h" 3 4 16 # 1 "/usr/include/i386-linux-gnu/gnu/stubs.h" 1 3 4 17 18 19 …… 855 856 857 858 # 3 "hello.c" 859 int main(){ 860 861 printf("Hello Word\n"); 862 return 0; 863 }
上述代码段中,行号1~858所代表的代码即是 ==#include <stdio.h>==所指向的内容,行号859~863的代码即是自己编写的main函数,可以看到,所标示的注释内容被清空了。
编译
预处理过程只是对文件的一个预处理,并没有进行语法的检查等。而且此时代码还只是C语言,需要先转换成汇编语言,这样的过程叫做编译。
XXXX@ubuntu:~/hello$ gcc -S hello.i -o hello.s XXXX@ubuntu:~/hello$ ls hello.c hello.i hello.s
说明:
1、gcc -S filename.i 表示对一个.i文件进行编译,S必须大写
2、gcc -S filename.i -o filename.s 表示把编译后的文件命名为filename.s,此处的 -o 必须小写
3、编译后的文件用 filename.s来表示。
用vim指令打开hello.s文件
1 .file "hello.c" 2 .section .rodata 3 .LC0: 4 .string "Hello Word" 5 .text 6 .globl main 7 .type main, @function 8 main: 9 .LFB0: 10 .cfi_startproc 11 leal 4(%esp), %ecx 12 .cfi_def_cfa 1, 0 …… 31 .cfi_def_cfa 4, 4 32 ret 33 .cfi_endproc 34 .LFE0: 35 .size main, .-main 36 .ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5 .4.0 20160609" 37 .section .note.GNU-stack,"",@progbits
此时的文件已经被翻译成AT&T汇编语言文件。
汇编
接下来,进行汇编语言到机器语言的翻译,这个过程叫汇编,过程结束后,生成目标文件.o。
XXXX@ubuntu:~/hello$ gcc -c hello.s XXXX@ubuntu:~/hello$ ls hello.c hello.i hello.o hello.s
说明:
1、-c 中的c一定要小写,不需要再加-o进行命名
2、hello.o是目标文件,是机器语言编写成的,但是还不可以执行,缺少必要的运行时文件。
链接
为了生成可执行文件,需要将运行时文件及目标文件进行绑定,这个过程即是链接,采用如下指令:
XXXX@ubuntu:~/hello$ gcc hello.o XXXX@ubuntu:~/hello$ ls a.out hello.c hello.i hello.o hello.s
此时 a.out可执行文件生成。
运行
运行可执行文件:
XXXX@ubuntu:~/hello$ ./a.out Hello Word
此时,输出结果Hello Word。
- linux预处理、编译、汇编、链接和运行的过程
- 【Linux】使用vim编写一个程序,gcc查看预处理、编译、汇编、链接过程
- Linux程序编译执行原理之一:预处理-编译-汇编-链接过程分析
- Linux预处理、编译、汇编、链接和运行的过程(包括一些基本的命令)
- Linux下C语言执行过程(预处理,编译,汇编,链接,执行)
- GCC 预处理 编译 汇编 链接全过程及其含义 程序的开始不是main函数
- 1.2.在linux环境实践,使用vim编写一个程序,然后使用gcc查看【预处理】、【编译】、【汇编】、【链接】各阶段文件的内容。并熟悉相关指令。
- Linux操作系统的简单指令及如何使用vim编写一个程序,然后使用gcc查看【预处理】、【编译】、【汇编】、【链接】各阶段文件的内容。
- Linux 环境下C编程指南-----gcc 编译的四大过程(预处理-编译-汇编-链接 )
- Linux下预处理,编译,汇编,链接过程及gdb的使用
- 汇编程序 在 linux下编译,链接,运行
- 程序执行期间发生了哪些事——预处理,编译,汇编,链接
- linux下编译,链接,运行汇编程序
- 程序的编译、链接、运行过程
- 预处理,编译,汇编,链接程序的区别
- 汇编语言自学习01_汇编程序实验工具及编译链接全过程
- C语言预处理、编译、汇编、链接过程
- C/C++程序编译流程(预处理->编译->汇编->链接)
- GCC编程四个过程:预处理-编译-汇编-链接
- 1.预处理,生成预编译文件(.文件): Gcc –E hello.c –o hello.i 2.编译,生成汇编代码(.s文件): Gcc –S hello.i –o hello.s 3.汇编,生成目标文件(.o文件): Gcc –c hello.s –o hello.o 4.链接,生成可执行文件: linux笔记