1 编译链接过程
预处理:编译 汇编 链接 【VS】项目——属性——C/C++——预处理器——预处理到文件(是)——生成.i文件
2 生成可执行文件
gcc -E main.c -o main.i
gcc -S main.i
gcc -c main.s
gcc main.o -o main
3 生成32位可执行文件
yum -y install glibc-devel.i686 glibc-devel
gcc -m32 main.c -o main32
gcc -m32 main.c -g main32
gcc -c -m32 main.c
gcc -E -m32 main.c -o main32.i
gcc -S -m32 main32.i
gcc -c -m32 main32.s
gcc main32.o -m32 -o main32
4 文件分析
int data1;
int data2 = 0 ;
int data3 = 10 ;
static int data4;
static int data5 = 0 ;
static int data6 = 20 ;
int main ( )
{
int a;
int b = 0 ;
int c = 30 ;
static int data7;
static int data8 = 0 ;
static int data9 = 40 ;
return 0 ;
}
4.1 二进制可重定位.o文件
objdump -h main.o
readelf -h main.o
readelf -S main.o
ll main.o
objdump -s main.o
objdump -t main.o
4.1.1 ELF Header
Entry point address 入口地址 Start of program headers program headers起始地址 Start of section headers section headers起始地址 Size of this header ELF header的大小 Size of section headers section header的大小 Number of section headers section header的数量
4.1.2 Section Headers
.text 代码,指令 .data 初始化且不为0的数据 .bss 未初始化或初始化为0的数据不需要存储具体数据 (只在符号表中标记) .symtab 符号表
.o文件大小 = 1100 =0x294(ELF Headers = 52 = 0x34 + Contents of sections) + 40 * 11(Section Headers) =660 + 440
4.1.3 SYMBOL TABLE符号表
size .data 3, (12 / 4) data3, data6, data9 .bss 5, (20 / 4) data2, data4, data5, data7, data8
data1:COM标记,弱符号(未初始化的非静态数据) 弱符号在连接过程中会被同名的强符号代替。
int a;
void fun ( )
{
a = 100 ;
}
# include <stdio.h>
short a = 10 ;
short b = 20 ;
void fun;
int main ( )
{
fun ( ) ;
printf ( "%d\n" , a) ;
printf ( "%d\n" , b) ;
return 0 ;
}
int a编译期:mov dword ptr [a], 64h main函数中,int a被同名强符号short a替代 此时执行:mov dword ptr [a], 64h 100二进制:0000 0000 0110 0100 小端:0110 0100 0000 0000 覆盖b的数据,b变为0
4.1.4 Contents of section .data
查看.data 段的内容:存储了具体数值
4.2 可执行.out文件
ld -e main -o run main.o
objdump -h main
objdump -s main
objdump -t main
readelf -h main
readelf -S main
readelf -l main
4.2.1 ELF Header
与.o文件相比,.out文件已经产生了虚拟入口地址 和program headers
4.2.2 .out文件大小
.out文件大小 = 16028 = 【ELF Headers】+【program headers】+ 【Contents of sections】+【Section Headers】
4.2.3 SYMBOL TABLE符号表
data1符号标记在.bss段 链接之后,弱符号会转化为强符号,或被强符号替代 符号表也显示:main函数处于.text段 此时,其他函数的声明也会由链接之前的 * UND * 标记转为存储在.text段 但是,动态库中的函数仍显示为 * UND * 标记
4.2.4 Contents of section .data
4.2.4 Program Headers和虚拟地址空间
LOAD 01 .text .rodata(存储常量) R,只读权限 页面大小 4k LOAD 02 .data .bss RW,可读可写权限 页面大小 4k
按页面存储,一个页面4k(0x1000 = 4096, 4096/1024 = 4) 多个段凑齐一个页面,存在页面对齐
虚拟地址空间 每个进程分配4G(32位,32条地址总线,标志的空间大小范围0 ~ 232 ) 地址映射 内存(物理内存,虚拟内存(磁盘划分的交换空间))
数据真实存储在内存中,通过虚拟地址空间映射到内存。