1-1 计算机系统漫游 “hello,world!”
生命周期:创建、编译、运行、退出
.c 源文件 – 编译系统 – .exe
# include<stdio.h>
int main(){
printf("hello,world!");
return 0;
}
linux> gcc -o hello hello.c
编译,产生hello.exe
PS:linux gcc 使用
预处理
根据#开头的代码,修改原始程序
例如:读取并插入头文件中的内容
得到hello.i
文本文件编译
.i
到.s
文件
详情见 [ 编译原理 ]汇编
.s
根据指令集将汇编程序.s
翻译成机器指令,按照固定的规则打包,得到可重定位的目标文件hello.o
,二进制文件,但是不能执行链接
调用了printf
函数,标准C库中(由编译器提供,代码翻译成指令)。并且这个函数是在printf.o
的文件中(提前编译好的目标文件)。
链接器,把两个.o
合并,按照一定规则调整,所以被称为可重定位目标文件。
链接之后产生hello.exe
,之后就能调入主存,执行程序
PS:有了集成环境,还分开看这个干啥?为什么要理解编译系统?
对机器执行的代码有一定的理解。优化程序性能
面试:
一个switch是不是比多个if-else高效?
一个函数调用的开销?
while循环比for循环更高效?需要第三章、第五章的知识
理解链接时出现的任务,
大型程序涉及各种程序库,很多奇怪的错误与链接器有关。甚至有些链接错误等到运行的时候才出现。例如:
静态变量和全局变量的区别
静态库和动态库的区别需要第七章知识
避免安全漏洞
缓冲区溢出 —— 互联网安全漏洞的主要原因例如:
数据和控制信息在程序栈上怎么存储?
不严谨不规范的书写会产生什么后果?第三章:堆栈的原理,缓冲区溢出错误,如何利用OS、编译器降低攻击风险。