文章目录
前言
学习c++前需要先了解一些底层知识,本文主要介绍进程空间内存分布和编译过程(x86 32 Linux平台下)
一、进程空间内存分布
进程的内存大小为4GB,其中,0x00000000~0xC000000这段内存地址为用户空间(0x00000000~0x00804000用户不可访问),0xC0000000~0xFFFFFFFF这段内存地址为内核空间。
对于每个进程而言,用户空间是独立的,内核空间是共享的。
用户空间
一个进程主要存放代码和数据,因此进程的用户空间主要被划分为代码段和数据段
代码段
.code:存放代码的段
数据段
一个程序中的数据又可以分为初始化但值不为0的全局变量或静态变量、未初始化或值为0的全局变量或静态变量和常量,因此数据段主要又可以划分以下几段:
.rdata:存放常量
.data:存放初始化但值不为0的全局变量或静态变量
.bss:存放未初始化或值为0的全局变量或静态变量
其他段
.heap:堆段
共享库:so文件
.stack:堆栈段
命令行参数和环境变量
内核空间
ZONE_DMA:专门分配给IO设备的DMA使用的一块内存
ZONE_NORMAL:内核能够直接使用的
ZONE_HIGHMEM:高端内存,内核不能够直接使用的
二、编译过程
四个阶段
从源文件编译生成可执行文件,需要经过4个阶段:预编译、编译、汇编和链接
预编译
处理#开头的代码,例如#include、#define(不包括#pragma)
编译
词法分析、语法分析、语义分析和中间代码优化…并生成汇编代码
汇编
为文件中的变量或函数产生对应的符号并生成目标文件(.obj),如果文件中的变量或函数引用的是其他文件中的变量或函数,不会为其产生符号,在链接阶段为其产生符号
链接
将各个目标文件(.obj)合并成一个可执行文件:
1、合并段,文件中没有产生符号的变量或函数会找到其定义的文件中的位置,生成符号
2、重定向,为符号生成地址
常见编译错误
符号未定义:汇编或链接阶段,没有找到变量或函数定义的位置,无法产生符号
符号重定义:汇编或链接阶段,产生相同的符号
总结
本文仅仅简单介绍了进程空间内存分布及编译过程,想要深入了解可以阅读《程序员的自我修养》和《深入理解计算机系统》