计算机程序编译执行过程

从源程序到可执行程序 (Back to Top)

探究程序(软件)是怎么在计算机上运行的

高级程序的分类:
• 编译型语言:C、C++、go等
• 解释型语言:JAVA、Python等

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

编译阶段:编译器(ccl)将文本文件“hello.i”翻译成文本文件“hello.s”,它包含一个汇编语言程序。该程序包含函数main的定义,如图所示。定义中2~7行的每条语句都以一种文本格式描述了一条低级机器语言指令。汇编语言是非常有用的,因为它为不同高级语言的不同编译器提供了通用的输出语言。例如,C编译器和Fortran编译器产生的输出文件用的都是一样的汇编语言。

汇编阶段:汇编器as 将hello.s翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在目标文件hello.o中。hello.o文件是一个二进制文件,它包含的17个字符是函数main的指令编码。如果我们用文本编辑器打开hello.o文件,将会是一堆乱码。

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

• hello.c源程序被编译器翻译成了可执行目标文件hello,并被存放在磁盘上。要想在Linux系统上运行该可执行文件,可以将文件名输入到称为shell的应用程序中,并得到运行的结果。

实验演示 (Back to Top)

实验环境:

  • OS:HUAWEI openEuler 20.03 arrch64
  • 编译器:gcc (GCC) 7.3.0

任何操作系统、编译器都可。

源代码(helloworld)

/*include head file*/
#include<stdio.h>
 
/*the main function*/
int main(int argc,char *argv[])
{
    printf("Hello World!");
    return 0 ;
}

Linux直接编译并运行(一步到位)

gcc hello  #直接执行,输出文件为 a.out
./a.out
或
gcc -o hello hello.c   #命名输出的为hello.c
./hello        #执行

在这里插入图片描述
在这里插入图片描述

分部编译

预处理:主要是处理源代码中以#开头的指令

例如本文hello world程序中的#include,预处理之后会将stdio.h的内容插入到预处理指令的位置

gcc -E -o hello.i hello.c  #-E参数表示只进行预处理,生成文件:hello.i
or
gcc -E hello.c -o hello.i

more hello.i #查看预处理文件

在这里插入图片描述

打开文件查看里面的内容,会发现stdio.h的位置被其实际内容所替代。预处理之后,注释内容也会被删除,宏定义会被展开
在这里插入图片描述

编译

预处理之后就需要对生成的预处理文件进行词法分析,语法分析,语义分析,最终产生汇编代码文件,说白点可以简单理解为将C代码“翻译”成汇编代码。

gcc -S -o hello.s hello.c #-S参数表示只到生成汇编为止

cat hello.s

在这里插入图片描述

汇编

汇编是将汇编代码翻译成机器可执行的指令,生成目标文件。整个过程较为简单,几乎只是按照汇编指令和机器指令进行一一翻译。

gcc  -o  hello.o  -c hello.c

cat hello.o #发现乱码
od helloWorld.o  #查看二进制内容

在这里插入图片描述

在这里插入图片描述

链接 (Back to Top)

链接是以某种方式将各个目标文件整合在一起,生成最后的可执行文件。我们的hello程序中调用了printf函数,但是并不存在于helloWorld.o中,而是存在于libc.so或libc.a中,因此我们需要通过链接将它们融合在一起。

gcc -o hello hello.c  #执行上面的命令之后,就得到了我们的helloWorld程序了,在linux下,它是一种ELF格式的文件(或者out 。 windows:exe)
ldd helloWorld   #我们可以通过ldd命令看到helloWorld程序链接了系统的库
    linux-vdso.so.1 =>  (0x00007ffe9ef11000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0d9f038000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f0d9f402000)

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值