在系统上运行程序(一)

写在开头

在调试项目时, 总会被一些问题困扰. 如, 无法解析xxxx符号等链接时错误, 故想弄清楚, 程序从文本文件到运行都有哪些过程和机制. 本系列文章更侧重于程序在链接时的一些原理和机制. 而对于编译阶段涉及较少, 一则由于还没有系统学习过编译原理相关知识; 二则现阶段更想解决自己在程序链接时的一些困惑.

文中如有错误,望大佬指教, 不喜轻喷!!!

从文本文件到可执行文件

对于C程序员来说, 应该都非常熟悉以下代码(hello.c)

#include <stdio.h>

int main()
{
    printf("hello, world\n");
    return 0;
}

虽然段代码非常简单, 但是要在系统上执行这个程序时, 系统发生了什么呢? 通过跟踪hello程序的生命周期来开始对系统的学习-----从它被创建开始, 到系统上运行, 输出简单的消息, 最后终止.

程序被其他程序翻译成不同的格式

hello程序的生命周期是从一个高级C语言程序开始的, 但是这种形式是人类可读的, 要在系统上运行hello.c程序, 就需要把条C语句转化为一系列低级的机器语言指令, 然后将这些指令按照一种称为可执行目标程序的格式打包,并以二进制磁盘文件的形式存放起来.

在*nix系统上, 从源文件到目标文件的转化是由编译器驱动程序完成的:

$ gcc hello.c -o hello

上述命令将源程序文件hello.c,翻译成一个可执行目标文件hello. 这个翻译过程可以分为四个阶段.

翻译过程的四个阶段

  • 预处理阶段: 预处理器根据以字符 # 开头的命令, 修改原始的C程序. 比如hello.c中的第一行的 #include<stdio.h> 命令告诉预处理器读取系统头文件 stdio.h中的内容, 并把它直接插入程序文本中. 从而得到了另一个C程序, 通常是以.i作为文件扩展名.

  • 编译阶段: 编译器将文本文件 hello.i 翻译成文本文件 hello.s, 它包含了一个汇编语言程序.

  • 汇编阶段: 汇编器将hello.s翻译成机器语言指令, 把这些指令打包成一种叫可重定位目标程序的格式, 并将结果保存在hello.o中.

  • 链接阶段: 在hello程序中, 我们调用了标准C库中的 printf 函数. 这个函数存在于一个名为printf.o的单独的预编译好了的目标文件中, 而这个文件必须以某种方式合并到我们的hello.o中, 链接器就负责处理这种合并. 结果得到一个名为hello的可执行目标文件, 可以被加载到内存中, 由系统执行.

经过编译器处理后, 源程序被翻译成了可执行目标文件hello, 并被存放在磁盘上.

$ ./hello

在shell中输入上述指令时, 系统就会加载并运行这个文件.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值