一、计算机语言
计算机是由二进制构成的,它只能听懂二进制也就是机器语言,但是普通人是无法看懂机器语言的,这个时候就需要一种电脑既能识别,人又能理解的语言,最先出现的就是汇编语言。但是汇编语言晦涩难懂,所以又出现了像C、C++、Java的高级语言。
所以计算机语言一般分为两种:低级语言(机器语言,汇编语言)和高级语言。使用高级语言编写的程序,经过编译转换成机器语言后才能运行,而汇编语言经过汇编器才能转换为机器语言。
汇编语言
汇编语言表示的代码清单示例:
mov eax,dword ptr [ebp-8] /* 把数值从内存复制到eax */ add eax,dword ptr [ebp-0Ch] /* 把eax的数值和内存的数值相加 */ mov dword ptr [ebp-4],eax /* 把eax的数值(上一步的结果)存储在内存中*/
这就是采用汇编语言(assembly)编写程序的一部分。汇编语言采用 助计符(memonic) 来编写程序,每一个原本是电信号的机器语言指令会有一个与其对应的助记符,例如:mov,add 分别是数据的存储(move)和相加(addition)的简写。汇编语言和机器语言时一 一对应的。这一点和高级语言有很大的不同,通常我们将汇编语言编写的程序转换为机器语言的过程称为 汇编;反之,机器语言转化为汇编语言的过程称为 反汇编。
汇编语言能够帮助你理解计算机做了什么工作,机器语言级别的程序时通过 寄存器 来处理的,上面代码中的 eax,ebp 都是表示的寄存器,是CPU内部寄存器的名称,所以可以说 CPU是一系列寄存器的集合体。在内存中的存储通过地址编号来表示,而寄存器的种类则通过名字来区分。
寄存器分类
不同类型的CPU。其内部寄存器的种类,数量以及寄存器的数值范围都是不同的。不过,根据功能的不同,可以将寄存器划分为下面几类:
种类 | 功能 |
累加寄存器 | 存取运行的数据和运算后的数据 |
标志寄存器 | 用于反应处理器的状态和运算结果的某些特征以及控制指令的执行 |
程序计数器 | 程序计数器是用于存放下一条指令所在单元的地址的地方 |
基址寄存器 | 存储数据内存的起始位置 |
变址寄存器 | 存储基址的相对地址 |
通用寄存器 | 存储任意数据 |
指令寄存器 | 储存正在被运行的指令,CPU内部使用,程序无法对该寄存器进行读写 |
栈寄存器 | 存储栈区域的起始位置 |
其中程序计数器、累加寄存器、标志寄存器、指令寄存器和栈寄存器都只有一个,其他寄存器一般有多个。
二、程序计数器
程序计数器(Program Counter)是用来存储下一条指令所在单元的地址。
程序执行时,PC的初值为程序第一条指令的地址,在顺序执行程序时,控制器首先按程序计数器所指出的指令地址从内存中取出一条指令,然后分析和执行该指令,同时将PC的值加1指向下一条要执行的指令。
可根据一个示例来看一下程序计数器的执行过程:
内存中配置程序示例
这是一段进行相加的操作,程序启动,在经过编译解析后会由操作系统把硬盘中的程序复制到内存中,示例中的程序将123和456执行相加操作,并将结果输出到显示屏上。由于使用机器语言难以描述,所以这里经过翻译后的结果,实际上每个指令和数据都可能分布在不同的地址上,但为了方便说明,把组成每一条的内存和数据放在一个内存地址上。
地址0100是程序运行的起始位置。Windows等操作系统把程序从硬盘复制到内存后,会将程序计数器作为设定为起始位置0100,然后执行程序,每执行一条指令后,程序计数器的数据会增加1(或者直接指向下一条指令的地址),然后,CPU就会根据程序计数器的数值,从内存中读取命令并执行,也就是说,程序计数器控制程序的流程。