- 程序是什么? 程序是计算机每一步动作的一组指令。
- 程序是有什么构成?
程序是指令和数据的组合体。例如printf("欢迎你");
printf为指令,而“欢迎你”为数据。 - 机器语言是什么?
CPU可以直接识别并使用的语言 - 正在运行的程序存储在什么位置
内存。 解析:硬盘和磁盘等媒介上报错的程序被复制到内存后才能运行。 - 什么是内存地址
内存中,用来表示命令和数据存储位置的数值。 解析:内存中保存命令和数据的场所,通过地址来标记和指定。地址有整数值表示。 - 计算机的构成元件中,负责程序的解释和运行的是哪个?
CPU。解析:计算机的构成元件中,根据程序的指令来进行数据运算,并控制整个计算机的设备称作CPU。
本章的重点内容
CPU的构成
CPU的运行机制,尤其是负责保存指令和数据的寄存器的机制。
章节结构
-
- CPU的内部结构解析(四个构成部分)
-
- CPU四个构成部分中的寄存器的整体作用和种类(主要的8种)
-
- 寄存器之一——程序计数器的作用(决定程序流程)
-
- 在 程序三大流程(顺序结构、循环结构、条件分支结构)中程序计数器到底是如何具体作用的。
-
- 另一重要的程序流程——函数调用,函数调用机制,即程序计数器在函数调用中如何具体作用的
-
机器语言指令的四个主要类型和功能
1. CPU的内部结构解析
- CPU的构造
- 程序运行机制——CPU四大件如何配合工作
CPU的构造
从功能方面看,CPU的内部由四个构成部分。分别为寄存器、控制器、运算器和时钟
- 寄存器可用来暂存指令、数据等处理对象。可以将其看做是内存的一种。
- 控制器负责把内存上的指令、数据等读入寄存器,并根据指令的执行结果来控制整个计算机。
- 运算器负责运算从内存读入寄存器的数据。
- 时钟负责发出CPU开始计时的时钟信号。
注:CPU和内存打交道。因此在这里顺便简单介绍一下内存。 在这里的内存是指计算机的主存储器(main memory),简称主存。 主存通过控制芯片等与CPU相连。
主存的作用:负责存储指令和数据。
主存的构成:主存由可读写的元素构成,每个字节(1字节=8位)都带有一个地址编号。 1Byte = 8bit;
程序运行机制——CPU四大件如何配合工作
程序启动后,根据时钟信号,控制器从内存中读取指令和数据。通过对这些指令加以解释和运行,运算器就会对数据进行运算,控制器根据该运算结果控制计算机。
控制:就是指数据运算以外的处理(主要是数据输入输出的时机控制)。如键盘和鼠标的输入,内存和磁盘等没见的输入输出、显示器和打印机的输出等。这些都是控制的内容。
2. CPU四个构成部分中的寄存器的整体作用和种类(主要的8种)
寄存器的整体作用
在程序中,程序是把寄存器作为对象来描述的。
意思就是说程序是把寄存器作为一个整体来看待。比如可以直接进行如下操作:把寄存器中的数据复制给某某,把某某的数据复制给寄存器。
在汇编语言下观察会更明显。
汇编语言:CPU可以直接识别并使用的语言。汇编语言采用助记符来编写程序,每一个原本是电气信号的机器语言指令都会有一个与其相对应的助记符。
汇编:把汇编语言编写的程序转化成机器语言的过程称为汇编。
反汇编:把机器语言程序转化成汇编语言的过程则称为反汇编。
寄存器的主要8个种类
寄存器 | 作用 |
---|---|
累加寄存器 | 存储执行运算的数据和运算后的数据 |
标志寄存器 | 存储运算处理后的CPU的状态 |
程序计数器 | 存储下一条指令所在内存的地址 |
基址寄存器 | 存储数据内存的起始地址 |
变址寄存器 | 存储基址寄存器的相对地址 |
通用寄存器 | 存储任一数据 |
指令寄存器 | 存储指令,CPU内部使用,程序员无法通过程序对该寄存器进行读写操作 |
栈寄存器 | 存储栈区域的起始地址 |
3. 寄存器之一——程序计数器的作用(决定程序流程)
程序启动时内存内容的模型。
- 用户发出启动程序的指令后,操作系统会把硬盘中保存的程序复制到内存中。
- 紧接着会将程序计数器设定为程序运行的开始地址(如0100),然后程序便开始运行。
- CPU每执行一个指令,程序计数器的值就会自动加1(注意,当执行的指令占据多个内存地址时,增加与指令长度相应的数值)。
- 然后CPU的控制器就会参照程序计数器的数值,从内存中读取命令并执行。
因此,程序计数器决定着程序的流程。
4. 在 程序三大流程(顺序结构、循环结构、条件分支结构)中程序计数器到底是如何具体作用的。
程序的流程分为顺序、条件分支和循环三种。
- 顺序执行是指按照地址内容的顺序执行指令
- 条件分支是指根据条件执行任一地址的指令。
- 循环是指重复执行同一地址的指令。
顺序执行:
CPU每执行一个指令,程序计数器的值就会自动加1(注意,当执行的指令占据多个内存地址时,增加与指令长度相应的数值)
条件分支:
在执行跳转到某个指令的同时,也间接的把程序计数器也设定成了要跳转到的那个指令的地址。
例子:把 内存中存储的数值123的绝对值输出到显示器的程序的内存状态
地址 | 内存中的内容 |
---|---|
0100 | 将 0106地址的数值保存在累加寄存器中 |
0101 | 比较累加寄存器的值和0大小 |
0102 | 值大于0则跳转到0104地址 // 在这里程序的流程直接跳转到了0104地址。 |
0103 | 将累加寄存器中的值得符号反过来 |
0104 | 将累加寄存器的值输出到显示器上 |
0105 | 结束程序 |
0106 | 数据123 |
循环时程序计数器的数值设定机制和条件分支程序计数器的数值设定机制一样
循环和条件分支中都使用到了跳转指令。
- 而该跳转指令,会参照当前执行的运算结果来判断是否需要跳转。
- 无论当前累加寄存器的运算结果是负数、正数还是零,标志寄存器都会将其保存(也负责存放溢出和奇偶校验的结果)。
- CPU在进行运算时,标志寄存器的数值就会根据运算结果自动设定。
- 条件分支在跳转指令前会进行比较运算。则有CPU在参考标志寄存器的数值后进行判断。
标志寄存器:运算结果的正、负、零三种状态由标志寄存器的三个位表示(1位就是一个位数的二进制数,表示0或1的数值)
而比较指令 就是在CPU内部做减法运算,减法运算的结果保存在标志寄存器中。若为正,则大于;若为0,则等于;若为负,则小于。
5. 另一重要的程序流程——函数调用,函数调用机制,即程序计数器在函数调用中如何具体作用的
函数调用与和其他流程(如条件分支、循环)的机制不同之处。
因为单纯的跳转指令无法实现函数的调用 。
函数的调用需要在完成函数内部的处理后,处理流程在返回到函数调用点(即函数调用指令的下一个地址)。
因此只是跳转到函数的入口处,处理流程就不知道应该返回值哪里了。
- 在机器语言中需要结合call指令和return指令来完成。
- 函数调用使用的是call指令。在通过函数的出口来调用return命令。
在将函数的入口地址设定到程序计数器之前,
call指令会把调用函数后要执行的指令地址(即主函数中调用函数语句的下一个指令/语句)存储在名为栈的主存内。函数处理完毕后,在通过函数的出口来调用return命令。
return命令的功能是把保存在栈中的地址设定到程序计数器中。
6. 通过地址和索引实现数组
基址寄存器和变址寄存器。
实际地址 = 基址寄存器的值+变址寄存器的值
7. 机器语言指令的四个主要类型和功能(CPU处理指令)
类型 | 功能 |
---|---|
数据传送指令 | 寄存器和内存、内存和内存、寄存器和外围设备之间的数据读写操作 |
运算指令 | 用累加寄存器执行算术运算、逻辑运算、比较运算和移位运算 |
跳转指令 | 实现条件分支、循环、强制跳转等 |
call/return指令 | 函数的调用/返回调用前的地址 |