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. [IOI2018]狼人——kruskal重构树+可持久化线段树

    题目链接: IOI2018werewolf 题目大意:给出一张$n$个点$m$条边的无向图,点和边可重复经过,一个狼人初始为人形,有$q$次询问,每次询问要求人形态只能处于编号不小于$L$的点,狼形态 ...

  2. BZOJ2595 WC2008游览计划(斯坦纳树)

    斯坦纳树板子题. 考虑状压dp,设f[i][j][S]表示当前在点(i,j)考虑转移,其所在的联通块包含的关键点集(至少)为S的答案. 转移时首先枚举子集,有f[i][j][S]=min{f[i][j ...

  3. java 前台使用枚举方法(二)

    最近发现,前台jsp使用枚举,有一个更方便的方法. 首先 枚举类的封装大家看一下:http://blog.csdn.net/hanjun0612/article/details/72845960 然后 ...

  4. jenkins和sonar的几个问题

    错误1:有个pom文件内容错了,但是在jenkins上面编译的时候,控制台将这个错误信息给打出来了,maven的编译也打印了failed with error,但是jenkins的job并没有因此而停 ...

  5. 2017ACM/ICPC广西邀请赛-重现赛

    HDU 6188 Duizi and Shunzi 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6188 思路: 签到题,以前写的. 实现代码: #inc ...

  6. java监控工具VisualVM

    java监控工具VisualVM https://visualvm.github.io/ https://visualvm.github.io/documentation.html https://h ...

  7. Leetcode 371.两整数之和 By Python

    不使用运算符 + 和 - ,计算两整数 a .b 之和. 示例 1: 输入: a = 1, b = 2 输出: 3 示例 2: 输入: a = -2, b = 3 输出: 1 思路 比如\(5+6=1 ...

  8. LOJ 2664. 「NOI2013」向量内积 解题报告

    #2664. 「NOI2013」向量内积 两个 \(d\) 维向量 \(A=[a_1, a_2 ,...,a_d]\) 与 \(B=[b_1 ,b_2 ,...,b_d]\) 的内积为其相对应维度的权 ...

  9. 爬虫json数据的处理

    在爬网页的过程中,最喜欢遇到的就是json数据接口,省了不少麻烦,但是json数据也有多种格式. 类型一:标准的json result = json.loads(html.text),将str转成py ...

  10. noip2013火柴排队_Solution

    要想对任意(ai,bi)和(aj­和b­j),当ai<aj时,都有bi<=bj:当ai>=aj时,bi>=bj,当对a进行升序排序后(b同时发生改变,从而不改变值,最后有a1& ...