【C++】面试基础重点知识

进程虚拟地址空间划分和布局

任何的编程语言=》 都会产生两种东西

1.指令

2.数据

当一个程序运行时,Linux操作系统会给当前进程分配一个2的32次方的一块虚拟地址空间 也就是4个G。(×86 32位Linux系统下)

拓展:

它存在,你可以看得见,它是物理的

它存在,你看不见,它是透明的

它不存在,你却可以看见,它是虚拟的

它不存在,你也看不见 , 它是被删除的

用户空间(3G):

0×00000000到0×08048000此段不可访问/读写

指令在运行时存放在代码段/.text段

.rodata 只读数据段

.data 数据段 存放初始化或者初始化不为0的

.bss 数据段 存放未初始化或者初始化为0的(内核会自动给该段数据清0)

.heap 堆空间

.加载动态链接库*.dll *so

stack 函数运行时栈空间

命令行参数和环境变量

此上为用户空间默认划分大小

内核空间(1G):

ZONE_DMA(16mb)

ZONE_NORMAL(800mb)

ZONE_HIGHMEN

全局变量 :不管是不是静态的 都叫做数据,编译后都会产生符号,初始化并不为0的都放在.data段

未初始化或初始化为0的都放在.bss段。

局部变量:编译不会产生符号,会生成指令。

比如 int a = 12; 会产生指令 mov dword ptr[a] , 0Ch,不管是否初始化后者初始化为0都会存放在.text段

但是对于静态局部变量,初始化了并且不为0,会存放在.data段。未初始化或者初始化为0 会存放在...bss段

注意:每一进程的用户空间是私有的,内核空间是共享的

函数调用堆栈的详细过程

cpp 复制代码
#include <iostream>

// 求和函数
int sum(int a, int b) 
{
	int temp = 0;
	temp = a+b;
    return temp;
}

int main() 
{
    // 测试求和函数
    int num1 = 10;
    int num2 = 20;
    int result = sum(num1, num2);
    std::cout << result << std::endl;

    return 0;
}

底层分析:

  • int num1 = 10;

    对应指令:mov dword ptr[ebp - 4],0Ah

  • int num1 = 20;

    对应指令:mov dword ptr[ebp - 8],14h

  • int result = sum(num1, num2);

    会先调用sum函数

    mov eax,dword ptr[ebp -8]

    push eax

    mov eax, dword ptr[ebp - 4]

    push eax

    call sum //自动将下一行地址压栈

    得到地址后

    add esp,8

    mov dword ptr[ebp-0Ch],eax

  • 进入左括号 int sum(int a, int b) {在原来的栈帧中开辟新空间

    底层指令 :

    push ebp

    mov ebp,esp

    sub esp,4Ch

    rep stos

    for

  • int temp = 0;

    底层指令:mov eax,dword ptr[ebp - 4],0

  • temp = a+b;

    底层指令:mov eax,dword ptr[ebp+8] a+b

    mov dword ptr[ebp-4],eax

  • return temp;

    底层指令:mov eax,dword ptr[ebp-4] 把temp的值保存在寄存器eax中

  • } //出右括号

    底层指令:mov esp,ebp

    pop ebp

    ret //出栈操作,把出栈的内容放入CPU的PC寄存器里

举例:

在函数外边可以正常打印里面的返回值,因为 栈内存空间的数据还在,但是当中间有调用别的函数就会覆盖此处的空间从而报错。所以这样的代码不安全。

编译过程:

预编译

#开头的命令,除了#pragma lib/link等

编译

g++/gcc -O

汇编

符号表的输出

二进制可重定位的目标文件(*.obj)

** . o文件格式

链接过程:

编译完成的所有.o文件 + 静态库文件

步骤一:所有.o文件段的合并,符号表合并后,进行符号解析

步骤二:符号的重定位(重定向)

符号解析成功后给所有的符号分配虚拟空间地址。

readelf -S main.o 查看各个段

相关推荐
会叫的恐龙2 分钟前
C++ 核心知识点汇总(第11日)(排序算法)
c++·算法·排序算法
twilight_4692 分钟前
机器学习与模式识别——线性回归算法
算法·机器学习·线性回归
玄同7659 分钟前
Python Random 模块深度解析:从基础 API 到 AI / 大模型工程化实践
人工智能·笔记·python·学习·算法·语言模型·llm
Pluchon12 分钟前
硅基计划4.0 算法 简单模拟实现位图&布隆过滤器
java·大数据·开发语言·数据结构·算法·哈希算法
符哥200813 分钟前
C++ 适合初学者的学习笔记整理
c++·笔记·学习
独断万古他化17 分钟前
【算法通关】前缀和:和为 K、和被 K整除、连续数组、矩阵区域和全解
算法·前缀和·矩阵·哈希表
历程里程碑19 分钟前
普通数组-----除了自身以外数组的乘积
大数据·javascript·python·算法·elasticsearch·搜索引擎·flask
AI视觉网奇22 分钟前
blender 导入fbx 黑色骨骼
学习·算法·ue5·blender
星火开发设计23 分钟前
this 指针:指向对象自身的隐含指针
开发语言·数据结构·c++·学习·指针·知识
梵刹古音24 分钟前
【C++】构造函数
开发语言·c++