1.     前记

我们知道,不同的计算机结构对RAM 的使用方式是有区别的,典型的计算机结构有两个,冯诺依曼结构和哈佛结构,而两大阵营的领军人物就是传说中的Intel X86系列的8086和51单片机系列的8051。请先对号入座,不理解的跳过去,继续往下看。

2.     What?

长啥样?

内存条,RAM中的一种,常见的应该是DDR SDRAM。相信各位都触摸过它,冷冰,无情,当然,你上电后它就变了样,暖暖的,无怨无悔的为我们干活。

嘿!别唬我,这个俺知道,51单片机。没错,51单片机里面也内置了RAM ,叫片内RAM。

这个就是一般嵌入式板卡上的RAM, 为了加以区分,就叫片外RAM。

广义上讲,CPU内部的寄存器也算是RAM的一种。

在哪里?

PC主板图片

嵌入式板卡图片

找一找你系统上的内存吧,再看看CPU datasheet 上有没有提到内置RAM。

特点是啥?

RAM(Random Access Memory),随机存储器。特点如下:

  • 如其名,可随时读写
  • 快,读写速度杠杠的,CPU最喜欢和它一起“玩”了
  • 掉电后,数据全部丢失,因此,别指望RAM中的数据长期存储,那么,我想要长期存储公司所有员工的数据怎么办?用FLASH吧。

请参考:

RAM、ROM、Flash的分类、性能比较

RAM,ROM,FLASH存储器区别

与CPU的连接方式

RAM是用来存储CPU计算所需的数据的,那么它怎么与CPU进行通话呢。就是通过那个叫做大巴士(Bus)的东东了,所有数据都是坐着大巴士在CPU和RAM 之间飘过来,再飘过去的。

3.     Why?

RAM特点决定了它的应用,保存计算过程中的数据。什么?不理解,举个例子,我想知道1+2等于多少?条件,写个程序,这活儿让必须由CPU干,看看过程:

  • CPU向RAM单元里“写入”两个操作数1和2(“写入”过程先飘过)
  • CPU从RAM指定单元中“读取”操作数1,操作数2,和运算指令“+”(“读取”过程也先飘过吧)
  • CPU解析读取的指令
  • CPU执行计算,给出结果3

执行过程中的“1”“2”“+”就是存储在RAM中的(当然可以用更简单的方法实现),执行完后,RAM中数据就没有存在的意义了,可以去干2+3等其他活了。这么简单的活儿当然没有必要CPU来完成,但是,如果领导非要你去确认一下1+1计算4294967295次这个“哲学”问题的结果的话,总不能找个小本本自己蛮干吧。看着就头大,可工作吗,总不能有情绪啊。

写个程序,扔给计算机,这哥们可是位任劳任怨的好公仆,喝杯茶,你就可以认真负责的交差啦。

好了,现在我们知道CPU虽然是个好同志,可是总有忙不过来的时候,那就请个秘书(存储器)帮忙吧!我们的存储器有很多种,寄存器,RAM系列,ROM系列,flash系列,还有硬盘,USB,SD卡(这哥仨比较特殊,请先记住,他们可读可写,掉电后数据不会丢失,先归到FLASH系列吧)等等。

那么,为什么CPU会选择RAM呢?我们先聊聊其他的。

为什么不是寄存器呢?前面提到过寄存器也是一种RAM,而且读写速度比片外的RAM还快。但是,寄存器是内嵌在CPU内部的,CPU就那么大点儿,能够内嵌的寄存器就那么几个,有的还有特殊用途,不能随便玩,仅用这几个存储单元,对CPU进行的复杂运算就无能为力了。

为什么不是ROM呢?从其特点看,这玩意儿相当稳定,Read Only嘛,轻易改变不了上面的内容,这也是为什么很多嵌入式系统将代码烧到ROM的原因了,随你风吹雨打,我自岿然不动。但是,你只让CPU看,不让CPU摸,CPU怎么把中间结果暂存到里面呢?

为什么不是FLASH呢?FLASH是可读可写的,这点与RAM没区别。但是,FLASH的写比较麻烦,不能直接写,只能先把原来的内容擦干净。CPU也是嫌麻烦的,多出来的擦过程意味着,CPU干正常活的时间变少了。不爽。还有,FLASH的读写是以块为单位的(NOR FLASH 块大小64~128KB,NAND FLASH块大小,8~32KB),这可不行啊,我就想用一个字节,影响太大了。而且,FLASH写入擦除速度也不敢恭维(NOR FLASH ,5s;NAND FLASH,4ms)。

再看看RAM吧,速度,价格,好而不贵,这里需要掌声!

种类

速度

单位存储价格

寄存器

ROM

NAND FLASH(FLASH)

SDROM(RAM)

CPU

上面的数据是同一板卡上各芯片的数据,因为技术发展得太快,不同时期的比较没有参考意义。

CPU在找“秘书”的时候郁闷了,Why?Why?Why there is always a “但是”,肿么办?看看价格,再看看速度,其他的东西都不理想,好吧,就是你了,瞎看什么,说你呢内存。

CPU选择存储器,这过程有点儿像“木桶”现象,CPU速度往往很快,因此,制约系统速度的那个短板就是存储器了。而随着技术的发展,单位存储的成本也在不断下降,相信,总有一天,现有存储器的区别将不再这样明晰,继而,从这个世界消失。一切只是时间而已。

4.     HOW?

CPU搭讪RAM

我们知道CPU和RAM是一对好基友。那么,CPU总得主动去搭讪吧。

存储器内部被划分为一个个的小格格,并且从0开始编号,例如,内存的容量是64K,那么就有64*1024个小格格啦。每个小格格可以用来读写1、2、3等等的数据。CPU如何操作呢?还记得大巴士嘛。三步走:

  • CPU通过地址总线,向存储器发送指令的地址信息
  • CPU通过控制总线,向存储器发送控制信息(读OR写)
  • CPU通过数据总线,从存储器读取数据或向存储器写入数据

我们来看看CPU从3号单元中读取数据的过程。(摘自:《汇编语言》)

  • CPU通过地址总线将地址信息3发出,我们可以看到,地址信息3就乘着巴士飘向RAM了
  • CPU通过控制总线发出读取命令,我们可以看到,“读取”信息乘着巴士也飘香RAM了
  • 存取器将3号单元中的数据8通过数据总线传回CPU,我们可以看到,数据信息8乘着数据巴士飘向CPU了。

是CODE还是DATA?

我们知道了CPU如何从RAM获取数据。那么CPU从存储器上得到数据后,这个数据是指令还是数据呢,如何区分呢?

其实,在存储器内部,指令和数据没有任何区别,都是二进制信息。CPU在发送读取命令前,会先明确,收到的数据是指令还是数据(CPU的主观想法),换句话说,CPU在读取数据前,告诉自己,收到的这个数据将作为指令,收到数据后,就把该数据解析为指令,并存储在CPU的指令缓存器中;如果在读取数据前,告诉自己,收到的数据将作为数据,那么,收到数据后,就把该数据解析为数据,存储到指定的寄存器中。

例如,存储器中的二进制信息1000100111011000,计算机可以把它看做大小为89D8H的数据来处理,也可以将其看做指令mov ax,bx来执行。

1000100111011000→89D8H(数据)

1000100111011000→mov ax,bx(指令)

CPU是怎么工作的?

请参考《汇编语言》 第2.10节 CS和IP

画图解释1+2过程,注意应该使用SS,SP,PUSH,POP。

传奇的冯诺依曼结构计算机

冯·诺依曼结构,又称为普林斯顿体系结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。取指令和取操作数都在同一总线上,通过分时复用的方式进行。不理解???来,看图解释(Intel 8086 CPU)。

8086是16位结构的CPU,它的寻址能力是216=64KB(补充,其实8086的地址总线是20位的,也就是说最大的地址范围是220=1MB,但是由于16位CPU一次只能处理16位数据,所以才是64KB的寻址范围,可见,总有拖后腿的~)。

冯氏结构认为,读取指令和数据并没有区别,所以虽然所有的存取器在物理上是独立的,但CPU对他们进行统一编号,在它眼里只有一个逻辑存储器。为什么这么搞?简单啊,CPU只要记住各段地址映射到哪个物理存储器就好了,然后就是发重复的读写命令就OK!

上图中虚拟内存空间各段地址分配如下:

地址0000H~7FFFH的32KB空间:指向内存条(RAM)

地址8000H~9FFFH的8KB空间:指向显存

地址A000H~FFFFH的24KB空间:指向各个ROM的地址

其实,冯氏结构还有一个好处, CPU封装简单,通俗讲就是管脚少,因为和所有存取器连接的地址总线,数据总线,控制总线是共用的。试想,如果CPU与每个存储芯片都有一套独立的地址总线,数据总线,控制总线,那么要想访问所有存储器芯片,CPU引脚最多将是现在的N(N为存储器个数)倍。

目前使用冯氏结构的CPU和微控制器有很多。其中包括英特尔公司的8086及其他CPU,TI的MSP430处理器,ARM公司的ARM7,MIPS公司的MIPS处理器。

怎么又冒出来个哈佛结构计算机?

按冯氏结构的构想,读指令和读数据的操作是分时复用的,但,这里有个严重问题,就是“读指令”的时候,“读数据”就得等着,“读数据”的时候,“读指令”的操作也得先等着。在通用计算机(PC机)上没有问题,但是对于一些像数字信号处理这样的应用来说,这是致命的问题。怎么办?好办,指令和数据分开就可以喽。下面是哈佛结构。

如图,哈佛结构的计算机由CPU、程序存储器(ROM或FLASH)和数据存储器(RAM)组成,程序存储器和数据存储器采用不同的总线,从而提供了较大的存储器带宽,使数据的移动和交换更加方便,尤其提供了较高的数字信号处理性能。

目前使用哈佛结构的中央处理器和微控制器有很多,除了Microchip公司的PIC系列芯片,还有摩托罗拉公司的MC68系列、Zilog公司的Z8系列、ATMEL公司的AVR系列和安谋公司的ARM9、ARM10和ARM11。

为什么很多嵌入式系统采用哈佛结构?除了指令的读取速度,还有一个重要因素要考虑的:稳定。下面是常见的场景:

我们的Windows电脑死机后:骂娘,重启,还没听说过有人去找微软理论吧~

我们的嵌入式系统死机后:停产,而且,这是会使人的…

为什么会死机呢?其实很多时候是我们的“不小心”,操作数据的时候不小心把指令改掉了,而如果程序和数据分开存储呢,系统会稳定很多。

参考:冯诺依曼、哈佛、RISC、CISC

1+2=?再算一遍

我们先这样假设,我们计算的程序代码(CODE)是“1+2=?”数据是(DATA)“1”“2”。(当然,这样的假设并不严谨,只是这样更便于理解)

典型冯氏结构,1+2执行过程:执行前,CODE+DATA就是一个文件,其实就是一个EXE文件,存储在硬盘里。当我们双击这个文件时,CPU将硬盘中的CODE+DATA拷贝到RAM中,并指向第一个指令,CPU开始执行。想想我们在Windows上打开Notepad.exe的过程吧,查看你的内存使用量是不是突然增加了一小块,因为Notepad.exe是要被拷贝到RAM中才可以执行的。

典型哈佛结构,1+2执行过程:上电前,CODE+DATA就是一个文件,通常叫做Firm,被烧写到ROM或FLASH中,上电后,CODE部分不动,CPU将ROM中的DATA部分拷贝到RAM中,此时,程序存储器(ROM或FLASH)中存储CODE,RAM中存储着DATA,此后,CPU分别读取CODE和DATA,在CPU内部去执行读取到的指令。

注意,我们这里说的是都是“典型”结构,因为现在2015年,嵌入式系统为了提高读取指令的速度,也会把所有的CODE+DATA拷贝的RAM中执行,毕竟,RAM的读取速度比ROM和FLASH都快嘛,这样的哈氏结构就有点儿像冯氏结构了。另一方面,Intel X86系列的CPU内部加入了指令和数据缓存,从效果看,已经可以同时读取指令和数据了,这样的冯氏结构,又有点儿像哈氏结构了。

因而目前大部分计算机体系都是CPU内部的哈氏结构+CPU外部的冯氏结构。这样各取所长,达到了一个平衡。

CODE在哪儿?

从上面的讨论中,我们可以知道,这个问题是要看计算机状态的。

典型冯氏结构

典型哈氏结构

运行前

硬盘,想想咱们的应用程序是不是在某个磁盘下。确切的说,是EXE文件中的CODE部分。

ROM或FLASH中的CODE部分

运行时

RAM里,是由CPU从硬盘里拷贝过来的

ROM或FLASH中的CODE部分

DATA在哪儿?

与CODE一样,这个问题是要看计算机状态的。

典型冯氏结构

典型哈氏结构

运行前

硬盘,想想咱们的应用程序是不是在某个磁盘下。确切的说,是EXE文件中的DATA部分。

ROM或FLASH中的DATA部分

运行时

RAM里,是由CPU从硬盘里拷贝过来的

ROM或FLASH中的DATA部分

RAM全干了什么?

RAM是一种存储器,它的作用当然是存储数据了。我们来看看RAM到底可以存储哪些数据。

  • 存储计算的过程数据,我们可以这样理解,在C语言中声明的临时变量就在这里,如1+2=?中的1和2
  • 存储常量数据,这些数据是不变的,比如软件的版本号信息
  • 存储程序代码,前提是,程序运行时才会将程序代码拷贝到RAM中,程序关闭后被释放
  • 存储内核代码(就是传说中的操作系统了),开机时,从ROM或FLASH中拷贝到RAM中,并长期驻留在RAM中,直到关机

RAM内部细分?

先看图:

由上面的讨论RAM的作用可以知道,内存可以按功能来细分,各个系统的叫法是有一点点儿区别的,请注意区分:

  • 代码区:简单的嵌入式系统,这个区只有类似1+2=?这样的代码。然而,像Windows和Linux这种含有操作系统的计算机,这个区包含内核代码和应用程序代码的。
  • 数据区:应用程序使用的数据,这个是可以再细分的
  • 堆栈区:这个单独聊

请谨记,这里所说的细分,只是我们使用内存的一种方法,本质上它仍然只负责存储数据,这样区分,只是概念性的。

堆栈

说起这个,得用一火车的话…

没有火车怎么办?简单聊。

目前为止,我们已经知道堆栈是RAM的一部分,他们依然是用于存储数据的,而且是人为划分的,那么,来看看他们的不同点吧。

栈(stack)

堆(heap)

谁分配的?

编译器和操作系统

编译器和操作系统

分配多大?

由你的程序决定,程序编译完后,大小就固定了

由你的程序决定。一支程序编译完后,CODE,DATA,STACK都是固定的,理论上其他的RAM都可以是Heap

分配的依据是什么?

MAP文件里记录了Stack的起始结束地址

你的程序里有没有malloc和new

有何用?

存储局部变量,参数

何时用?

函数调用时

申请未知大小的空间

怎么用?

代码中的声明的局部变量,在调用时都会入栈

主动申请:malloc和new

主动释放:free和delete

何时开始?

程序运行时

程序运行时AND程序主动申请

何时结束?

程序结束时

程序主动释放OR程序结束时

请参考:

What and where are the stack and heap? 里面干货很多,好好读读吧

什么是堆和栈,它们在哪儿? 如果你实在懒得不行,看看这个,是上文的不完整翻译

一只程序有多大?为什么?

这里指的是,PC上的EXE文件,嵌入式的FIRM文件大小。前面我们讨论过,你的程序中CODE,DATA, STACT大小是固定的,而且是编译后就决定了,因此你的程序大小由你程序中使用的CODE,DATA, STACT大小决定。

一只程序可用内存多大?为什么?

这个还用问吗?当然是RAM有多大就可以用多大。这在嵌入式系统中没有问题,你有一片128MB的RAM,自然就拥有了128MB的使用权。但在PC上你不觉得奇怪吗?假设你的PC上安装的是Windows7 32-bit OS,插着一条4GB的内存条,那理论上,最大的RAM寻址空间是232=4GB,你安装了Office2010。

我们来这样操作一下,打开一个Word文档,我们可以肯定,Word可用的RAM是这个内存条的4GB空间。我们再打开一个Excel文档,Excel可用的RAM是多少?答案是:理论上也可以有4GB。

为什么?现在的操作系统都支持多进程(Windows和Linux都支持),每个应用程序就是一个进程,对于一个进程而言,进程独享整个内存。其实,操作系统搞了个虚拟内存的东东,我们说内存独享整个内存,是指独享整个虚拟内存(虚拟内存会保持与物理内存的映射关系)。为什么这么干?每个程序(进程)是可能占用很大内存的,为什么说可能呢,因为Heap的动态变化。而通常情况下,这支程序(进程)内存的占有量并不大,过百M的程序已经算是内存大户了。如果进程占用整个物理内存,别的进程就别玩了。

所以,现在的策略是每个进程独享虚拟内存,多个虚拟内存共享物理内存,这样,大家就可以一起快乐的玩耍啦!

请参考:

Linux内存点滴 用户进程内存空间

Linux 虚拟内存和物理内存的理解

程序(进程)内存分布 解析

Linux 内存映射函数 mmap()函数详解

MAP文件作用

查查你的MAP文件就知道了,它是记录你的程序,在RAM上的地址信息的。

5.     后记

我们回到原点,回答问题。

WHAT:RAM是个读写速度很快的存储器;

WHY:从速度和成本考虑RAM最适合于与CPU协同工作;

HOW:不同的计算机结构对RAM的使用方式是不同的。

不同系统往往要考虑两件事:成本,速度。从上面的讨论中可以看出,每个体统在选择芯片以及结构的时候,都在权衡这两件事,只是侧重点不同而已。记住,这两个不是东西的东西很重要,它们最终决定了你的系统的样子。

6.     参考文章:

. 汇编语言 王爽 第二版

. RAM、ROM、Flash的分类、性能比较

. RAM,ROM,FLASH存储器区别

. 单片机下程序 RAM, ROM ,Flash

. ARM中的Flash和RAM

. What and where are the stack and heap?

. 程序运行时是在flash中还是在RAM

. 单片机程序程序存储空间(ROM)和数据存储空间(RAM)详解

. 什么是堆和栈,它们在哪儿?

. C语言内存分布图

. 32位系统最大只能支持4GB内存之由来

. 深入Linux启动流程

. 冯诺依曼、哈佛、RISC、CISC

. 普林斯顿结构 VS 哈佛结构

. 关于冯诺依曼结构、哈佛结构、增强型的哈佛结构

. 程序(进程)内存分布 解析

. Linux 内存映射函数 mmap()函数详解

. Linux 虚拟内存和物理内存的理解

. Linux内存点滴 用户进程内存空间

RAM的更多相关文章

  1. Suspend to RAM和Suspend to Idle分析,以及在HiKey上性能对比

    Linux内核suspend状态 Linux内核支持多种类型的睡眠状态,通过设置不同的模块进入低功耗模式来达到省电功能.目前存在四种模式:suspend to idle.power-on standb ...

  2. asp.net mvc4 简单的服务器监控开发之C#获取服务器CPU、RAM、TCP等系统信息(上)

    一.背景 前段时间服务器出了点问题,加上学业愈来愈紧张,写博文分享的时间越来越少.虽然不是第一次在博客园上写经验,但是近期分享的博文得到了不少的朋友支持和指正,在这里内心非常感激和开心.希望以后能认真 ...

  3. RAM、DRAM、SD卡

    catalogue . ROM.RAM.DRAM.SRAM和FLASH的区别 . 内存工作原理 . DRAM基本结构与原理 . SD卡基本结构与原理 1. ROM.RAM.DRAM.SRAM和FLAS ...

  4. RAM和ROM总结

    RAM和ROM总结 一.在解释之前先备注一些缩写的全称便于记忆: 1.EPROM:(Electrically Programmable Read-Only-Memory)电可编程序只读存储器 2.EE ...

  5. RAM清理器

    或许有些氨基小白不知道RAM是什么,官方的解释是"运行内存" 只要你的RAM够大,你玩什么都不卡! 今天给大家带来的就是 <RAM清理器>!!体积小,能量大就是我给他介 ...

  6. RAM,SRAM,DRAM,SDRAM,DDR RAM,ROM,PROM,EPROM,EEPROM,NAND FLASH,NOR FLASH的区别

    RAM:由字面意思就可以理解,SDRAM SRAM DRAM(下面蓝色字体的这几种)都可以统称RAM,random access memory(随机存取存储器)的缩写,下面是51hei.com为大家整 ...

  7. 调试2440 RAM拷贝至SDRAM遇到的问题

    汇编代码主要是初始化一些寄存器,关狗,初始化时钟,初始化存储管理器以便访问内存,然后将SoC上4k RAM数据拷贝至SDRAM,然后在SRAM里面运行,由于代码未正常跑起来,于是使用JLinkExe来 ...

  8. 手机的ROM,RAM是各自存放什么?所谓“运行内存”和“机身内存”究竟有什么区别?

    手机的内存分为运行内存(RAM)和非运行内存(也叫机身内存.储存空间.ROM) 1.手机的内存,分为存储内存和运行内存,相当于电脑的硬盘和内存条.2.存储内存分为机身内存和存储卡.3.rom是存储内存 ...

  9. RAM与ROM

    随着对计算机行业的深入了解,很多人开始听到一些RAM和ROM的讨论话题,之前我也不是很清楚,也不知道他和电脑的内存有什么联系.下面就让我们一起来学习一下这个吧. 首先RAM和ROM是什么 RAM和RO ...

  10. STM32 USB CAN 学习笔记 - 共享RAM的用法

    USB 时钟可以一直使能. 如果CAN时钟没有使能,RAM 能被软件读写.(CANBus 不能发送和接受Message) 如果CAN时钟使能,RAM不能软件被写. CANBus Core 控制此RAM ...

随机推荐

  1. IOS使用pods初次加载出现Pods-resources.sh: Permission denied错误的解决方案

    在使用了pods之后首次编译加载时会出现错误 你的Pods存放目录/Pods/Target Support Files/Pods/Pods-resources.sh: Permission denie ...

  2. ES6 学习笔记之二 块作用域与闭包

    "闭包是函数和声明该函数的词法环境的组合." 这是MDN上对闭包的定义. <JavaScript高级程序设计>中则是这样定义的:闭包是指有权访问另一个函数作用域中的变量 ...

  3. GitHub中开启二次验证Two-factor authentication,如何在命令行下更新和上传代码

    最近在使用GitHub管理代码,在git命令行管理代码时候遇到一些问题.如果开起了二次验证(Two-factor authentication两个要素认证),命令行会一直提示输入用户名和密码.查找了一 ...

  4. vagrant系列教程(二):vagrant的配置文件vagrantfile详解(转)

    原文:http://blog.csdn.net/hel12he/article/details/51089774 上一篇文章完整的讲叙了如何安装一个vagrant的环境.这里主要说一说vagrant的 ...

  5. dedecms判断当前页面是否为首页 织梦设置首页高亮

    做织梦网站导航栏时,我们一般需要设置当前栏目高亮显示,这个使用currentstyle就能直接实现,但是如果在首页时怎么让首页模块高亮呢? 织梦当前栏目高亮: <style>.hover{ ...

  6. 二分图最大匹配模板【匈牙利;Dinic最大流】

    二分图最大匹配模板[匈牙利:Dinic最大流] 匈牙利算法 int n,m; vector<int> map[100010]; int match[100010];//保存匹配的互相点 b ...

  7. Visual Studio 2017 Enterprise 发布 15.4 版本,离线安装包百度网盘下载。

    Visual Studio 2017 于2017年10月13日发布 15.4 版本.该版本包含多项生产力改进,支持 .NET Standard 2.0 ,并且可以开启 Xamarin Live Pla ...

  8. Mysql 远程登录及常用命令

    第一招.mysql服务的启动和停止 net stop mysql net start mysql 第二招.登陆mysql 语法如下: mysql -u用户名 -p用户密码 键入命令mysql -uro ...

  9. CentOS7上安装FTP服务

    ---------------------------------------------------------------------------------------------------- ...

  10. ActiveRecord的生命周期

    ActiveRecord的生命周期,通过方法重写和插入我们需要的业务逻辑来达到我们对程序的控制. 示例: 1,beforeSave() public function beforeSave($inse ...