当前位置: 首页 > article >正文

c++ 基础 计算机的内存和寻址机制

计算机的内存和寻址机制

CPU通过地址总线访问内存中的指令和数据,RAM提供临时存储,ROM存储固件,Cache加速数据访问。这些部件协同工作,完成代码的加载、解码、执行和结果存储。

微处理器

微处理器是计算机的核心部件,负责执行指令和处理数据。

  • 主要组件
    • ALU(算术逻辑单元):执行算术和逻辑运算。
    • CU(控制单元):从内存中提取指令并解码,控制其他部件工作。
    • 寄存器(Registers):高速存储单元,用于临时存放数据和地址。
      • 例如:程序计数器(PC)、指令寄存器(IR)、累加器(ACC)等。
  • 工作过程
    1. 取指令(Fetch):从内存中读取下一条指令。
    2. 解码指令(Decode):解析指令的操作码和操作数。
    3. 执行指令(Execute):执行指令(如算术运算、数据移动等)。
    4. 写回结果(Writeback):将结果写回寄存器或内存。

内存

内存是计算机用于存储数据和指令的硬件部件,分为RAM(随机存取存储器)**和**ROM(只读存储器)

  • RAM(Random Access Memory) ,也叫主存(堆、栈等):
    • 特点:可读写、易失性(断电后数据丢失)。
    • 作用:存储正在运行的程序和数据,供CPU快速访问。通常作为操作系统或其他正在运行中的程序的临时数据存储媒介。
    • 分类:
      • DRAM(动态RAM):需要定期刷新,常用于主内存。
      • SRAM(静态RAM):速度快,常用于高速缓存(Cache)。
  • ROM(Read-Only Memory)
    • 特点:只读、非易失性(断电后数据不丢失)。
    • 作用:存储固件(如BIOS/UEFI)和启动程序。

寻址

寻址是指CPU通过内存地址访问内存中的数据或指令的过程。内存被划分为多个存储单元,每个单元有一个唯一的地址。

  • 地址总线(Address Bus)
    • 用于传输内存地址,决定CPU可以访问的内存空间大小。
    • 例如,32位地址总线可以寻址(2^32) 4GB 的内存空间。
  • 数据总线(Data Bus)
    • 用于在CPU和内存之间传输数据,宽度决定每次可以传输的数据量。
    • 例如,64位数据总线一次可以传输8字节数据。
  • 控制总线(Control Bus)
    • 用于传输控制信号,如读/写信号、时钟信号等。

补充: 64位数据总线一次可以传输8字节数据

1. 理解“位”和“字节”

  • 位(bit):计算机中最小的数据单位,表示一个二进制位(0或1)。
  • 字节(byte):由8个二进制位组成,是计算机中常用的数据单位。

2. 数据总线的宽度

  • 数据总线的宽度决定了CPU和内存之间一次可以传输的数据量。
  • 64位数据总线意味着总线可以同时传输64个二进制位。

3. 计算传输的字节数

  • 1字节 = 8位。

  • 因此,64位数据总线一次可以传输的字节数为:

在这里插入图片描述


4. 举例说明

假设CPU通过64位数据总线从内存中读取数据:

  • 数据总线一次可以传输64位数据。
  • 64位数据 = 8字节数据(因为64 ÷ 8 = 8)。

高速缓存(Cache)

  • 位于CPU和RAM之间,用于存储频繁访问的数据和指令
  • 分为L1、L2、L3三级缓存,速度依次降低,容量依次增大。
  • 作用:减少CPU访问内存的延迟,提高程序执行效率。

计算机执行代码的详细过程

(1)加载程序
  • 操作系统将程序从硬盘加载到内存(RAM)中。
  • 程序包括代码段(存放指令)、数据段(存放数据)和堆栈段(用于函数调用和局部变量)。
(2)初始化
  • CPU从程序的入口点(通常是main函数)开始执行。
  • 程序计数器(PC)指向第一条指令的地址。
(3)指令周期
  • 取指令
    • CPU通过地址总线发送指令地址,从内存中读取指令。
    • 指令被加载到指令寄存器(IR)中。
  • 解码指令
    • 控制单元(CU)解析指令的操作码和操作数。
  • 执行指令
    • ALU执行算术或逻辑运算。
    • 数据可能从内存加载到寄存器,或从寄存器写回内存。
  • 更新程序计数器
    • PC指向下一条指令的地址。
(4)数据处理
  • 数据从内存加载到寄存器,供CPU处理。
  • 处理结果可能写回内存或输出到外部设备。
(5)函数调用
  • 当调用函数时:
    • 返回地址和局部变量被压入堆栈。
    • PC跳转到函数的入口地址。
  • 函数返回时:
    • 从堆栈中弹出返回地址,PC跳转回调用点。
(6)程序结束
  • 程序执行完毕后,操作系统释放内存资源。

示例

假设有以下C语言代码:

复制

int main() {
    int a = 10;
    int b = 20;
    int c = a + b;
    return c;
}
执行过程:
  1. 加载程序
    • 操作系统将程序加载到内存中。
  2. 初始化
    • CPU从main函数开始执行。
  3. 指令周期
    • 取指令:读取int a = 10;
    • 解码指令:解析为“将10存储到变量a”。
    • 执行指令:将10写入内存中的变量a。
    • 重复上述过程,执行int b = 20;int c = a + b;
  4. 数据处理
    • ALU计算a + b,结果存储到变量c。
  5. 程序结束
    • 返回结果,操作系统释放内存。

堆栈

**栈(Stack)堆(Heap)都是位于RAM(随机存取存储器)**中的内存区域。RAM是计算机的主内存,用于存储正在运行的程序和数据。栈和堆是RAM中两个不同的内存管理区域,它们的作用和管理方式不同,但都依赖于RAM的物理存储。

  • 用于存储局部变量和函数调用上下文,自动管理,速度快但大小有限。
  • 用于动态分配内存,手动管理,速度较慢但大小较大。

栈和堆在RAM中的布局

1. RAM的作用

RAM是计算机的临时存储设备,具有以下特点:

  • 易失性:断电后数据丢失。
  • 高速访问:比硬盘等存储设备快得多。
  • 随机访问:可以直接访问任意地址的数据。

RAM中存储的内容包括:

  • 操作系统内核。
  • 正在运行的程序(代码段、数据段、堆栈段等)。
  • 动态分配的内存(堆)。

2. 栈在RAM中

  • 位置:栈通常位于RAM的高地址区域,向低地址方向增长。
  • 管理:栈的内存分配和释放由编译器自动管理。
  • 特点
    • 存储局部变量、函数参数、返回地址等。
    • 内存分配连续,访问速度快。
    • 大小有限,通常为几MB(具体取决于操作系统和编程语言)。

3. 堆在RAM中

  • 位置:堆通常位于RAM的低地址区域,向高地址方向增长。
  • 管理:堆的内存分配和释放由程序员手动管理(如C/C++中的malloc/freenew/delete)。
  • 特点
    • 存储动态分配的数据(如数组、对象等)。
    • 内存分配不连续,可能产生碎片。
    • 大小较大,受限于系统的可用内存。
+---------------------+ 高地址
|       栈(Stack)     |
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
|                     |
+---------------------+
|        堆(Heap)     |
|                     |
|                     |
|                     |
|                     |
+---------------------+
|   未分配的内存空间    |
|                     |
+---------------------+
|   全局/静态变量区     |
|   (数据段)          |
+---------------------+
|   程序代码区         |
|   (代码段)          |
+---------------------+ 低地址
  • :从高地址向低地址增长。
  • :从低地址向高地址增长。
  • 代码段:存储程序的指令(如函数代码)。
  • 数据段:存储全局变量和静态变量。
  1. 栈和堆的使用

    #include <stdio.h>
    #include <stdlib.h>
    
    int global_var = 10; // 全局变量,存储在数据段
    
    void stackExample() {
        int a = 10; // 局部变量a存储在栈中
        int b = 20; // 局部变量b存储在栈中
        printf("Stack: a = %d, b = %d\n", a, b);
        // 函数结束时,a和b自动释放
    }
    
    void heapExample() {
        int* arr = (int*)malloc(5 * sizeof(int)); // 在堆中分配5个整数的内存
        if (arr != NULL) {
            for (int i = 0; i < 5; i++) {
                arr[i] = i + 1; // 初始化数组
            }
            printf("Heap: arr = ");
            for (int i = 0; i < 5; i++) {
                printf("%d ", arr[i]); // 打印数组
            }
            printf("\n");
            free(arr); // 显式释放堆内存
        }
    }
    
    int main() {
        stackExample(); // 调用栈示例函数
        heapExample();  // 调用堆示例函数
        return 0;
    }
    
  2. 堆栈溢出

  • 栈溢出(Stack Overflow)
    • 当栈空间不足时发生(如递归调用过深或局部变量过多)。
    • 解决方法:优化递归、减少局部变量使用或增加栈大小。
  • 堆溢出(Heap Overflow)
    • 当堆空间不足时发生(如动态分配过多内存)。
    • 解决方法:优化内存管理、释放不再使用的内存。

http://www.kler.cn/a/534538.html

相关文章:

  • Java 大视界 -- Java 大数据在智能教育中的应用与个性化学习(75)
  • 【Java计算机毕业设计】基于Springboot的物业信息管理系统【源代码+数据库+LW文档+开题报告+答辩稿+部署教程+代码讲解】
  • 【大数据技术】搭建完全分布式高可用大数据集群(Hadoop+MapReduce+Yarn)
  • DeepSeek-R1:开源机器人智能控制系统的革命性突破
  • 《redis哨兵机制》
  • (篇一)基于PyDracula搭建一个深度学习的界面之添加启动界面
  • Redis面试题总结(题目来源JavaGuide)
  • LeetCode 3442.奇偶频次间的最大差值 I
  • ASP.NET Core筛选器Filter
  • Vue3.5常用特性整理
  • 一、tsp学习笔记——开发环境搭建
  • 计算机网络笔记再战——理解几个经典的协议6——TCP与UDP
  • Mysql-增删改查(知识点总结)
  • WPS的word文档加密
  • module ‘matplotlib.cm‘ has no attribute ‘get_cmap‘
  • 在https下引用IC卡读卡器web插件
  • LeetCode 257.二叉树的所有路径
  • BUU10 [极客大挑战 2019]LoveSQL1
  • RK3576——USB3.2 OTG无法识别到USB设备
  • docker容器编排工具 docker compose
  • 【Elasticsearch】 邻接矩阵聚合(Adjacency Matrix Aggregation)
  • ASP.NET Core中间件Markdown转换器
  • 数据加载器--不同文档数据格式的加载方法
  • seata 1.3.0 本地安装步骤
  • go-zero学习笔记(四)
  • python(自学10-2)获取豆瓣页面 下载成json格式