阿里云个人不能开网站/南昌seo实用技巧
链接器将多个可重定位目标文件合并成可执行目标文件,可执行目标文件格式同可重定位目标文件的格式大致相似。ELF头部描述文件的总体信息。它还包括程序的入口点(entry point) 。它指向程序执行时第一条指令的地址。.text .data .rodata各部分节都被重定位到运行时内存地址。
其中包含一个 .init节 其定义了一个小函数,程序的初始化代码会将其调用。另外,可执行文件是完全链接的(符号均已经被重定位),所以它不需要.rel 节。
objdump -h main 通过objdump查看main可执行文件的内容格式
可以看到同可重定位目标文件类似,可执行目标文件主要由各部分节组成:
- .CODE 指明的代码段
- .RODATA 只读数据节(如printf中字符常量)
- .DATA 数据节(对应于全局变量(静态变量)数据)
- ......
可以看到 多个模块的.data .text等节 被合并在一起,体现在可执行文件中它们都进行了组合(相邻)。
【加载可执行目标文件】
通过Linux shell 直接执行即:
linux> ./main
因为main不是一个内置的shell命令,所以shell 认为main是一个可执行的目标文件,也就是通过调用内核的加载器(loader)来执行它。加载器将可执行目标文件的代码和数据从磁盘复制到内存中,并跳转到程序的第一条指令处。
一个Linux程序存在一个运行时内存区域。X86-64地址从0x400000 开始:
各个区域分别为:
只读代码段:即对应目标文件的.text 二进制代码节、.rodata 只读数据段 、.init 程序初始化函数
读写段:也称数据段,对应于源文件中全局变量(静态变量)
运行时堆:程序执行过程中动态创建的数据,堆的地址向上生长。
运行时栈:程序执行过程中局部变量的创建与销毁,过程调用参数传递,返回地址等在栈中创建与销毁。栈的地址向下生长。
程序计数器:PC指向当前程序的执行位置。
用户栈的最大合法地址为2的48次方-1 从2的48次方开始,为内核区域的代码和数据。
内核:操作系统常驻内存的部分。