编译 链接 运行原理

一、

在80386之前是实模式,80386之后是保护模式

所谓的32位、62位是指 ALU的宽度,即一次性能处理最大数据长度(比特为单位)

在Windows操作系统下4G虚拟内存空间是,用户空间:内核空间是1:1

在Linux操作系统下4G虚拟内存空间是,用户空间:内核空间是3:1

Linux4G虚拟地址空间分配大致如下图

                                                                   图1

.data 已初始化且初始化不为0的数据

.bss 未初始化或初始化为0的数据

局部变量的普通变量是指令(.text)

二、

编译

预编译

生成.i文件  命令:gcc -E main.c -o main.o

1.删除#define

2.递归展开#include文件

3.删除#if0 #endif #elif

4.删除注释(//  /**/)

5.添加行,文件表示

6.保留#pragma

编译

生成.s文件 命令:gcc -S main.i -o main.s

1.词法分析

2.语法分析

3.语义分析

4.代码优化

汇编

可重定位,可重入

生成.o文件或.obj文件 gcc -c main.s -o main.o

指令代码翻译成二进制

链接

生成.exe文件

1.合并段和符号表

2.符号解析(在符号引用的地方找到符号定义的地方(只关注全局符号))

3.分配地址和空间

4.符号重定位

三、目标文件的分析

可执行文件格式,Windows下问PE格式,Linux下为ELF格式,它们都是COFF格式的变种。目标文件就是源码编译后但未进行连接的那些中间文件,它跟可执行文件的内容结构很相似,所以一般跟可执行文件格式一起采用一种格式存储。

在此,使用main.c进行分析

编译

输入gcc -c *.c 命令对main.c文件进行编译生成main.o文件

查看目标文件的结构和内容:objdump -h main.o

由此可画出ELF文件的大致结构

 

我们可以发现在.bss文件中大小为20,但我们的main.c 程序中有6个int 型的数据在.bss段中存放,缺失了一个……

这时我们查看符号表

发现!!!缺失的那个数据  gdata3在*COM*块中

这是因为,

在c中,有强弱符号之分

强符号:已初始化的全局变量

弱符号:未初始化的全局变量

规则:

1.两强(两个同名强):重定义

2.一强一弱:选强符号

3.两弱:选字节较大的

 

此时函数的入口地址为0x0000 0000

 

链接

输入命令ld -e main -o run main.o

此时有了入口地址

gdata3此时归属于.bss段了

 

ps:

修改main.c    添加sum.c

此时gdata、sum处于*UND*块

通过链接

四、运行原理

1.创建虚拟地址空间和物理内存的映射(映射结构体)

2.加载指令数据

查看program header 段

3.第一行指令的地址写入pc寄存器中

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值