编译链接
代码--编译-->二进制可重定位文件--链接-->二进制可执行文件--执行-->为进程分配虚拟地址空间--地址映射-->内存/IO磁盘
虚拟地址空间:以32位操作系统为例,给每个进程划分一个执行空间,大小4G。其中3G为用户空间,1G为内核空间。
32位系统的虚拟地址空间为什么是4G?
一共有32条地址总线能标志的最小地址0000 0000,能标志的最大空间ffff ffff。2^32=4G,也就是能表示的最大范围。
编译在单文件进行,链接在多文件进行

数据的存储 / 数据段:(上图中数据与指令中的数据)
. bss段存储没有初始化或者初始化为0的数据
.data段存储初始化且初始化值不为0的数据
函数调用过程
参数入栈 -> 函数栈帧开辟 -> 返回值返回 -> 函数栈退出
1.参数入栈(小于等于8,大于8)
4字节参数入栈
顺序 从右向左
方式 使用寄存器push带入
8字节参数入栈
顺序 从右向左
方式 使用寄存器push带入
>8
12字节参数入栈
顺序 从右向左
方式 先在栈顶开辟足够该参数的空间,之后将数据复制进去
c++ 中只要是自定义类型,无论多大字节,都采用先开辟空间,之后赋值的方式
2.函数栈帧开辟
将调用方函数(我调用其他函数,我是调用方)的下一行指令地址入栈
将调用方函数的栈底寄存器入栈
让ebp=esp
让esp=esp-*** (在栈里面,减是向低地址增长)
将其他使用的寄存器入栈
将新开辟的栈帧空间中全部写为ccccccccc
3.返回值返回(小于等于8,大于8)
4字节返回值
方式:将返回值放入寄存器带回
8字节返回值
方式:将返回值放在两个寄存器,带回
>8字节
12字节返回值:
方式:
在函数参数入栈之后,入栈一个地址。地址是调用方栈帧上的地址(是靠近调用方函数栈帧的栈顶的位置)(调用方指的是调用其他函数的一方)
在返回值返回的时候,将返回数据写入到上面入栈的调用方地址上
返回之后,将从该地址上将数据取出
c++中,自定义类型都按照入栈调用方地址的方式
4.函数栈退出
进行当前函数栈帧的校验
将线程保护的寄存器出栈
让esp=ebp
ebp= pop
将下一行指令的地址还原
清除参数