程序是保存在硬盘中的,要载入内存才能运行,CPU也被设计为只能从内存中读取数据和指令。
对于CPU来说,内存仅仅是一个存放指令和数据的地方,并不能在内存中完成计算功能,
如:计算a= b+ c, 必须将a, b, c都读取到CPU内部才能进行加法运算。
CPU结构如下:
  
 
其中运算单元:是CPU的大脑,负责加减乘除,比较,位移等运算。
寄存器:CPU内部非常小,非常快速的存储不见,容量很有限,对于64 位的CPU,每个寄存器一般能存储64 位(8 个字节)的数据。一般:现代CPU内置了几十个或几百个寄存器,嵌入式系统功能单一,寄存器数量较少。(我们经常说的CPU多少位,指的就是寄存器的位数)
用途:完成数学运算,控制循环次数,程序的执行流程等。
缓存:虽然内存读取速度已经很快了,但和CPU比,相差甚远,如果每次偶读从内存读取数据,会严重拖慢CPU的运行速度。缓存容量是有限的,对于不是很频繁使用的数据,会绕过缓存,直接到内存中读取。
CPU指令:要让CPU工作,必须借助特定的指令,例:add用于加法运算,sub除法等。
假设有下面的C语言代码:
int  a =  0X14 ,  b =  0XAE ,  c; 
c =  a +  b; 
在VS2010 Debug模式下生成的CPU指令为:
mov  ptr[ a] ,  0X14 
mov  ptr[ b] ,  0XAE 
mov  eax,  ptr[ a] 
add  eax,  ptr[ b] 
mov  ptr[ c] ,  eax
  
虚拟内存:
代码: 
# include  <stdio.h>  
# include  <stdlib.h>  
int  a =  1 ,  b =  255 ; 
int  main ( ) { 
    int  * pa =  & a; 
    printf ( "pa = %#X, &b = %#X\n" ,  pa,  & b) ; 
    system ( "pause" ) ; 
    return  0 ; 
} 
结果:
pa =  0X402000 ,  & b =  0X402004 
代码a,b是全局变量,他们的内存地址在链接时就已经决定了,再也不能改变,所以程序运行结果都是一样的。
问题:若物理内存中的这两个地址被其他程序占用了,程序是否无法运行?
幸运的是,这些内存地址都是假的,不是真实的物理内存地址,而是虚拟地址。虚拟地址通过CPU的转换才能对应到物理地址,且每次程序运行,操作系统都会重新安排虚拟地址和物理地址的对应关系,
哪一段物理内存空闲就使用哪一段,如下图:
  
 
虚拟地址:程序给出的地址,通过某种映射的方法,将虚拟地址转换为实际的物理地址。
只有我们可以妥善的控制这个映射过程,就可保证每次运行时都使用相同的地址。
例:上面代码中变量 a 的地址是 0X402000 ,第一次运行时它对应的物理内存地址可能是 0X12ED90AA ,第二次运行时可能又对应 0XED90 ,而我们的程序不需要关心这些,这些繁杂
的内存管理工作交给操作系统处理即可。
除了编程时可以使用固定的内存地址,给程序员带了方便,使用虚拟地址还能使得不同程序
的地址空间相互隔离,提供内存使用率。
1. 使不同程序的地址空间相互隔离:
使用虚拟地址后,程序A和B虽然都可访问同一个地址,但他们对应的物理地址是不同的,无论如何操作,都不会修改对方的内存。
2. 提高内存使用效率
使用虚拟地址后,操作系统会更多地介入到内存管理工作中,这使得控制内存权限成为可能。