0、开篇

   (1)程序是什么?
         指示计算机每一步动作的一组指令
    (2)程序是由什么组成的?
         指令和数据
    (3)什么是机器语言?
         CPU可以直接识别并使用的语言
    (4)正在运行的程序存储在什么位置?
         内存
    (5)什么是内存地址?
         内存中,用来表示命令和数据存储位置的数值
    (6)计算机的构成元件中,负责程序的解释和运行是哪个?
        CPU
 

1、CPU的内部结构解析

    ① CPU所负责的就是解释和运行最终转换成机器语言的程序内容。如下图所示:
    
 
    ② CPU的内部由寄存器、控制器、运算器和时钟四个部分构成,各部分之间由电流信号相互连通。
    寄存器:暂存指令、数据等处理对象;
    控制器:把内存上的指令、数据等读入寄存器;
    运算器:运算从内存读入寄存器的数据;
    时钟:发出CPU开始计时的时钟信号;(时钟信号的频率越高,CPU的运行速度就越快)
    
 
    ③ 内存,通过控制芯片与CPU相连,主要负责存储指令和数据。内存由可读写的元素构成,每个字节(1字节=8位)都带有一个地址编号。CPU可以通过该地址读取主存中的指令和数据,当然也可以写入数据。
Warn:内存中存储的指令和数据会随着计算机的关机而自动清除。因为其通常使用DRAM(Dynamic Random Access Memory,动态随机存取存储器)芯片。
 
    ④ 通过了解CPU的构造后,程序的运行机制大概如下:
程序启动后,根据时钟信号,控制器会从内存中读取指令和数据。通过对这些指令加以解释和运行,运算器就会对数据进行运算,控制器根据该运算结果来控制计算机。

2、CPU是寄存器的集合体

    ① CPU的四个构成部分中,程序员只需要了解寄存器即可。因为程序是把寄存器作为对象来描述的。
不同类型的CPU,其内部寄存器的数量、种类以及寄存器存储的数值范围都是不同的。不过,根据功能的不同,我们可以将寄存器大致分为8类,如下图:
    
    可以看出,寄存器中存储的内容既可以是指令也可以是数据。其中数据分为“用于运算的数值”和“表示内存地址的数值”两种。它们使用的寄存器也是不同的。用于运算的数值放在累加寄存器中存储,表示内存地址的数值则放在基址寄存器和变址寄存器中存储。
 
    ② 对程序员来说,CPU就是各种功能的寄存器的集合体。其中,程序计数器、累加寄存器、标志寄存器、指令寄存器和栈寄存器都只有一个,其他的寄存器一般有多个。
如下图所示,程序员眼中的CPU
   
 

3、决定程序流程的程序计数器

    存储指令和数据的内存,是通过地址来划分的:
   
    上图可知:程序计数器决定这程序的流程,实际上,一个命令和数据通常被存储在多个地址上,上图只是为了便于说明,把指令、数据分配到了一个地址中。
 

4、条件分支和循环分支

    ① 程序的流程一般有三种:顺序执行、条件执行和循环三种。
顺序执行的情况比较简单,每执行一个指令程序计数器的值就自动加1;但若程序中存在条件分支和循环,机器语言的指令就可以将程序计数器的值设定为任意地址。
    下图会以条件分支为例:
     
    程序运行的开始位置是0100地址。随着程序计数器数值的增加,当达到0102地址时,如果累加寄存器的值是正数,则执行跳转指令(jump指令)跳转到0104地址。此时,由于累加寄存器的值时123,为正数,因为0103地址的指令被跳过,程序的流程直接跳转到了0104地址。也就是说,“跳转到0104地址”这个指令间接执行了“将程序计数器设定为0104地址”这个操作。
 
    ② 条件分支和循环分支使用的跳转指令,会参照当前执行的运算结果。结果是存储在标志寄存器中的(也负责存放溢出和奇偶校验的结果)
    

32位CPU(寄存器的长度是32位)

标志寄存器的数值会根据运算结果自动设定。至于是否执行跳转指令,则由CPU在参考标志寄存器的数值后进行判断。运算结果的正、零、负三种状态由标志寄存器的三个位表示,标志寄存器的第一个字节位、第二个字节位和第三个字节位的值位1时,表示运算结果分别为正数、零和负数。

5、函数的调用机制

    函数调用处理也是通过把程序计数器的值设定成函数的存储地址来实现的。不过,这和条件分支、循环的机制所有不同,因为单纯的跳转指令无法实现函数的调用。函数的调用需要在完成函数内部的处理后,处理流程再返回到函数调用点(函数调用指令的下一个地址)。因此,如果只是跳转到函数的入口地址,处理流程就不知道应该返回至哪里去。
    鉴于这个问题,机器语言的call指令和return指令能够解决这个问题。
    在将函数的入口地址设定到程序计数器之前,call指令会把调用函数后要执行的指令地址存储在名为栈的主存内。函数处理完毕后,再通过函数的出口来执行return命令。
    return命令的功能是把保存在栈中的地址设定到程序计数器中。
    

在编译高级编程语言的程序后,函数调用的处理会转换成call指令,函数结束的处理则会转换成return指令。这样一来程序的运行也就变得非常流畅。

6、通过地址和索引实现数组

    这一小节就要说到基址寄存器和变址寄存器了。通过这两个寄存器,我们可以对主内存上特定的内存区域进行划分,从而实现类似于数组的操作。
    首先,我们用十六进制数将计算机内存上00000000~FFFFFFFF的地址划分出来。那么,凡是该范围的内存区域,只要有一个32位的寄存器,即可查看全部的内存地址。但如果想要像数组那样分割特定的内存区域以达到连续查看的目的,使用两个寄存器会更方便。如下图所示:
    

假设要查看10000000~1000FFFF地址时,如上图所示,可以将1000000存入基址期存器,并使变址寄存器的值在00000000~0000FFFF变化,CPU则会把基址寄存区+变址寄存器的值解释为实际查看的内存地址。

7、CPU的处理其实很简单

CPU可以进行的处理不多,下图列举一些:

一:对程序员来说CPU是什么?的更多相关文章

  1. (第一章)对程序员来说CPU是什么

    这几天,看到一本书,<程序是怎么跑起来的>,觉得之前都没有完整的看完一本书,现在要从这本书开始,慢慢的培养自己写读书笔记的习惯,不能度过去就忘了. 学习是一个螺旋上升的过程,不要指望一下子 ...

  2. 《程序是怎样跑起来的》读书笔记——第一章 对程序员来说CPU是什么

    1 程序的运行流程 2 CPU的组成 3 寄存器的主要种类和功能 "程序计数器"--决定程序流程的 4 条件分支和循环机制 4.1 顺序执行 4.2 选择分支 5 函数的调用机制 ...

  3. 【python】对于程序员来说,2018刑侦科推理试卷是问题么?

    最近网上很火的2018刑侦科推理试卷,题目确实很考验人逻辑思维能力. 可是对于程序员来说,这根本不是问题.写个程序用穷举法计算一遍即可,太简单. import itertools class Solu ...

  4. 8个对程序员来说有用的jQuery小贴士和技巧

    1) 禁用鼠标右键单击 jQuery程序员可以使用此代码在网页上禁用鼠标右键点击. 1 2 3 4 5 6 7 8 9 10 $(document).ready(function() {     // ...

  5. 大一C语言学习笔记(3)---对于程序员来说,学历和能力,到底哪个重要?

    在高考失利后,我合理地萎靡一段时间,振作起来之后选择了我憧憬了10年的计算机专业---软件工程.但由于分数受限,也是选择了二本普通院校黑科技(我当然爱她,我的母校),而因为学历上的自卑,让我有了想考研 ...

  6. 对java程序员来说时间格式永远让人挠头来看Java Date Time 教程-时间测量

    在Java中,用System.currentTimeMillis()来测量时间最方便. 你要做的是在某些操作之前获取到时间,然后在这些操作之后你想要测量时间,算出时间差.下面是一个例子: long s ...

  7. 每个程序员都应该了解的 CPU 高速缓存

    每个程序员都应该了解的 CPU 高速缓存 英文原文:Memory part 2: CPU caches 来源:oschina [编者按:这是Ulrich Drepper写“程序员都该知道存储器”的第二 ...

  8. 如何成为一个C++高级程序员

    C++这门语言从诞生到今天已经经历了将近30个年头.不可否认,它的学习难度都比其它语言较高.而它的学习难度,主要来自于它的复杂性.现在C++的使用范围比以前已经少了很多,java.C#.python等 ...

  9. 程序员的自我修养(2)——计算机网络(转) good

    相关文章:程序员的自我修养——操作系统篇 几乎所有的计算机程序,都会牵涉到网络通信.因此,了解计算机基础网络知识,对每一个程序员来说都是异常重要的. 本文在介绍一些基础网络知识的同时,给出了一些高质量 ...

随机推荐

  1. ELK--filebeat命令行参数解释

    ./filebeat 使用-c命令行上的标志设置要加载的配置文件,可以通过重复-c标志来指定多个配置文件, 可以使用覆盖个别设置-E <setting>=<value>.< ...

  2. Uva1001-floyd算法-建图

    给出一些球,球内的时间为零,球之间的速度为10每单位. 给两个点,求最短时间. 把每一个球当做点,球间的距离就是floyd的d数组.之后跑一遍floyd wa了两发因为d数组定义成int了 #incl ...

  3. LightOJ - 1341 Aladdin and the Flying Carpet (算术基本定理)

    题意: 就是....求a的所有大于b的因子有多少对 算术基本定理求 所有因子 阿欧...偷张图. 注意范围 就好  ..... 解析: 在1 -1012的范围内求大于b的所有a的因子的对数(有几对) ...

  4. Real mode & Protected mode

    [转]  https://objectkuan.gitbooks.io/ucore-docs/content/lab1/lab1_3_2_1_protection_mode.html 为何要了解Int ...

  5. BZOJ2839 : 集合计数 (广义容斥定理)

    题目 一个有 \(N\) 个 元素的集合有 \(2^N\) 个不同子集(包含空集), 现在要在这 \(2^N\) 个集合中取出若干集合(至少一个), 使得它们的交集的元素个数为 \(K\) ,求取法的 ...

  6. BZOJ 5308 [ZJOI2018] Day2T2 胖 | 二分 ST表

    题目链接 LOJ 2529 BZOJ 5308 题解 这么简单的题 为什么考场上我完全想不清楚 = = 对于k个关键点中的每一个关键点\(a\),二分它能一度成为哪些点的最短路起点(显然这些点在一段包 ...

  7. centos6.5重新调整/home和跟目录/大小

    0. 说明 系统刚刚安装完之后,默认到/home有1.5TiB,而根分区只有200G.现在是要将VolGroup-lv_home缩小到200G,并将剩余的空间添加给VolGroup-lv_root. ...

  8. P1274 魔术数字游戏 naive搜索+剪枝

    真的naive...... 我把所有能剪的枝都剪了才过的.否则就是TTT 还有个很神奇的事:数组作为参数传进递归函数时会造成上一层函数里的数组的改变.这个我TM调了一天. 下面奉上代码 #includ ...

  9. js的append拼接html丢失css样式解决

    htmlApp += "<li id='leftli"+lunci+"'>"; htmlApp += "<span id='left ...

  10. 多线程状态下调用SimpleDateFormat.format()抛出 ArrayIndexOutOfBoundsException 异常

    本来想在类的顶部设置一个 静态的SimpleDateFormat常量 public final static DateFormat dateFormatGMT = new SimpleDateForm ...