编译、链接、运行的过程?

编译、链接、运行的过程?


编译

分为3部,预编译,编译,汇编。
1、预编译主要是对条件预编译指令的处理;
【1】宏的展开
【2】头文件的引入
【3】把所有的注释都替换为空格
【4】保留所有#pragma
2、编译主要是进行代码优化和符号汇总;
【1】扫描
【2】语法分析
【3】语义分析
【4】源代码优化
【5】代码生成
【6】目标代码的优化
3、汇编主要是根据对应关系把汇编指令转换为本地操作系统对应的机器码
==>生成可重定位目标文件,在可重定位目标文件中,也有各种段,其中有一个符号表段,并且此时的符号表为分配虚拟地址,使用的是无效地址,因此.o文件不能执行。


链接

就是把所有的.o文件和库文件链接起来,链接分两步:
第一步:
把所有的.o文件的各个段合并起来,其中对符号表段的合并就是符号解析,当一个符号在段中找到多个定义(重定义)或者未找到定义(未定义)就会发生链接错误。符号解析正确后,就会给符号表分配虚拟地址。
第二步:
进行符号重定向(就是把指令中所有的无效地址均修改成正确的虚拟地址)


编译链接图示

编译链接描述图


运行

1、创建虚拟地址空间到物理内存的映射(创建内核地址映射结构体),创建页目录和页表。
2、加载代码段和数据段
3、把可执行文件的入口地址写到cpu的pc寄存器里
(主函数的地址)

可执行文件的组成格式:
这里写图片描述
为什么能执行?从哪开始执行?CPU如何得知从哪开始执行?

由于program headers中有两个load页面,这两个页面指示操作系统LOAD加载器,把当前程序中的东西加载到一个页面上。从主函数起始地址开始执行。cpu从ELF header中得到入口地址(entry point address)。

把磁盘上的代码段和数据段映射到虚拟地址空间的.test和.data段再通过地址映射到物理内存上。第一次页面映射必然以失败告终!引起缺页异常,启动缺页异常处理程序,处理完成之后,重启地址映射!
这里写图片描述
虚拟地址通过cpu内总线到MMU计算(地址映射)得到物理内存的地址通过系统总线访问到物理内存。
这里写图片描述


相关重要问题的概括:

1、为什么不直接给程序分配物理内存,而要引入虚拟地址空间,通过地址映射来分配访问物理内存呢?

若直接给程序分配物理内存,程序并未执行,当程序运行时,事先分配的物理内存可能被其他正在运行的进程占用,而系统给程序分配的物理内存也在此处,同时在一块物理内存中运行,必然会失败。而引入虚拟地址空间,运行时,会进行虚拟地址映射,第一次以失败告终,由于没有给程序分配物理内存而引起的缺页异常,此时给进程分配物理内存,不会发生之前的情况。


2、.O文件为什么不能运行?

首先介绍一下.o文件的的格式
这里写图片描述

没有program head段,且由于没有给符号表段的符号分配有效的虚拟地址,指令段的地址也都是无效地址,所以.o文件即使运行也找不到正确的虚拟地址。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值