C++ 编译链接

main.c

预编译  main.i

      删除注释

      头文件引入

      宏展开

编译  main.s

      代码优化

       汇总所有的符号

汇编  main.o  二进制可重定位文件

     根据特定平台 将汇编指令转换成机器码

      构建 .o(obj) 文件

链接  可执行文件

      1 合并所有obj文件的段,并调整段偏移和段长度,合并符号表

      2 链接二点核心:符号重定位  注意强弱符号

         符号处理只对所有obj文件的global符号进行处理

        local 的符号不做处理  static 修饰的就是local

        符号解析完成后 就分配内存地址(虚拟地址)

        符号解析就是所有obj符号表中对符号引用的地方都要找到该符号定义的地方

     3 所有相同属性的段进行合并组织在一个页面,调整段偏移和长度

        然后符合并号表,

        然后给符号分配内存地址  

                         函数符号地址存的是偏移量,因为函数调用要跳到别的代码段。

                         函数符号的真实地址是,下一行指令 + 偏移量

         然后给符号重定位 

objdump -h main.o   打印obj文件的段

readelf -h main.o  打印 elf  文件头

信息: 平台  体系  入口地址  文件头大小 52 字节

bss 段不占elf文件的空间,占虚拟内存的空间

bss段的初始都为0  不需要存储,存储是为了记录初始值

每个段都会记录在段表中

file main.o  查看文件属性

readelf -S main.o  查看所有段

.text    AX 可读可执行

.data  WA 可读可写

.bss   WA 可读可写

.comment

.note.GNU-stack

.shstrtab

.symtab   符号表段

.strtab

objdump -d main.o  查看机器码 和汇编

objdump -s main.o 打印段的内容

char *p = "hello world"; 常量字符串在 .rodata (只读数据段)

C语言种有强符号和弱符号的概念  初始化的是强符号 未初始化的是弱符号

C语言:多个强符号 编译出错

              强符号和弱符号 选强符号

               多个弱符号选 占用内存最大的弱符号

objdump -t main.o  查看符号所在的段

A.c  文件要引用 B.c 文件中的变量, 需要在A.c 或A.h 中 extern int data;

汇编中 数据的地方地址都是 00 00 00 00 

            函数的地方都是 fc  ff  ff  ff 

           pc 寄存器保持下一条执行的指令  

程序的运行

1 创建虚拟地址空间到物理内存的映射(创建内核地址映射结构体)创建页目录和页表

2 加载代码段和数据段

3 把可执行文件的入口地址写到CPU的pc寄存器

你可能感兴趣的:(c++,开发语言)