程序存放数据的机制

程序存放数据的机制

程序的运行依赖于CPU,而我们知道,CPU只负责计算,本身不具备智能。CPU的每一步执行都要我们告诉它怎么做,输入一条指令,它就运行一次,然后停下来,等待下一条指令。这些指令都是二进制的,称为操作码。对于人类来说,二进制程序是不可读的,根本看不出来机器干了什么。但我们都知道,我们写代码并是直接使用二进制来写的,现在大部分人都是用高级编程语言来编写程序,这些高级编程语言通过编译器或解释器的作用就可以翻译成一条条操作码。
先来看寄存器。CPU本身只负责运算,不负责储存数据。数据一般都储存在内存之中,CPU要用的时候就去内存读写数据。但是,CPU的运算速度远高于内存的读写速度,为了避免被拖慢,CPU 都自带缓存。基本上,CPU缓存可以看作是读写速度较快的内存。但是,CPU缓存还是不够快,另外数据在缓存里面的地址是不固定的,CPU每次读写都要寻址也会拖慢速度。因此,除了缓存之外,CPU还自带了寄存器,用来储存最常用的数据。也就是说,那些最频繁读写的数据(比如循环变量),都会放在寄存器里面,CPU优先读写寄存器,再由寄存器跟内存交换数据。寄存器不依靠地址区分数据,而依靠名称。每一个寄存器都有自己的名称,我们告诉 CPU去具体的哪一个寄存器拿数据,这样的速度是最快的。
早期的CPU只有8个寄存器,而且每个都有不同的用途,而现在的寄存器已经有100多个了,并且都变成了通用寄存器,不特别指定用途。我们常常看到32位CPU、64位CPU 这样的名称,其实指的就是寄存器的大小。寄存器只能存放很少量的数据,大多数时候,CPU 要指挥寄存器,直接跟内存交换数据。所以,除了寄存器,还必须了解内存怎么储存数据。
内存有两种模型,堆(Heap)和栈(Stack)。程序运行时,操作系统会给它分配一段内存用来储存程序和运行产生的数据。这段内存有起始地址和结束地址,起始地址是较小的那个地址,而结束地址是较大的那个地址。程序运行的过程中,对于动态的内存占用请求(比如新建对象或者使用malloc命令),系统就会从预先分配好的那段内存之中,划出一部分给用户。这种有用户主动申请而划分出来的内存区域就叫做堆(Heap),它是由起始低位地址到高位地址增长。堆有个重要的特点就是不会自动消失,而是需要用户自己手动释放或者由垃圾回收机制回收。
另一种内存占用叫做栈(Stack)简单来说,栈就是由于函数运行而产生的临时占用内存区域。当主函数main运行时,系统会在内存里建立一个帧,所有main函数里的内部变量都会储存在这个帧里面,当这个函数执行结束后,该帧就会被回收,释放所有的内部变量,不再占用空间。如果在main函数里调用函数,当程序读到这行时,系统就会再建立一个帧来储存这个函数里的内部变量,所以,一般来说,调用栈有多少层,就会有多少帧。当调用函数结束时,它的帧就会被回收,系统会回到主调函数中断的位置继续执行。通过这种机制,就实现了函数的层层调用,并且每一层都能使用自己的本地变量。所有的帧都存放在栈中,而且都是一层层叠加的,所有最晚入栈的帧最早出栈。每一次函数结束后,都会释放一个帧,当所有的函数执行完成,整个栈就释放了。栈是由内存区域的结束地址开始,从高位地址向低位地址分配的。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值