机器码、CPU指令集还有汇编编程是面对机器最底层的三个层次。基本的思路是按高级语言编写的程序由编译器或解释器翻译成汇编语言代码,然后再由汇编器翻译成机器码。 汇编编程实际上最终面对的是机器码,那么为什么要涉及指令集这个玩意呢。在计算机中,简单或复杂的功能模块都是由逻辑门搭建而成的。这些功能模块的具体功能通过指令集来表示,至于CPU具体有哪些功能,具体包含哪些模块,CPU设计者会设计出具体的指令集,并通过功能模块搭建而成。因为指令集它不是数字序列,除了算术学家,没人想对着一堆数字思考,数学家喜欢符号,学生可能觉得符号望而生畏很难适应,那是因为他暂时还没意识到直接对着数字想那是有多困难。
当我们开始起名字的时候,数字就不单纯是数字了,所以我说指令集是一种抽象是一种理想。 我们在说汇编指令的时候提到CPU需要的是数字序列也就是机器码,这个转换过程叫汇编,可以理解为“汇总、编辑”,汇总之前实际还涉及一些替换以及四则运算。汇总的意思是,我们编写的这些CPU机器码的文字性表示也许分散在几个不同的地方,所以我们需要汇总起来。编辑的意思是,我们会在汇编指令之间(又或者是末尾或开头)插入一些标记,在转换成机器码之前它们需要适时换成此处的数字前总共有多少个数字,我们有一些汇编指令会需要这个数量。 那么我们为这个转换,也就说汇编,编写的工具叫做汇编器。汇编器的作者,他也不想只对着一堆数字思考。他参照指令集来考虑,实现这样一套工具。有了汇编器,我们就可以做汇编编程了,当然是照着这个汇编器的规则来编程。 那么,重点来了,为什么高级语言编译器要把源代码转成汇编指令呢。对于编译器作者有很多个理由可以这么做:
对于CPU指令集,其中肯定有条加法指令。比如Add R1 R2 。我们可以认为这条指令的意思是计算寄存器R1中的内容和R2的和,然后把结果存到R1寄存器中。 那么经过编译后这条指令会变成二进制,比如010100010010 。这条二进制指令一共12位。明显可以分为三大部分。最前面的0101表示这是条加法指令,后面0001说的是第一个操作数是寄存器1,最后0010说的是第二个数就是寄存器2(其实实际没有这么简单的指令,至少应该区分操作数是寄存器还是直接的数据,但为了把这说的更容易理解作了简化)。我们可以通过十二根导线把这条指令输入一个CPU中。导线通电就是1,不通电就是0 。为了叙述方便我们从左到右用A0-A11给这12根导线编上号。 然后计算机会分析这条指令。步骤如下: 1 最开始的两根导线A0和A1,第一根有电第二根没电,就能知道这是一条运算指令(而非存储器操作或者跳转等指令)。那么指令将被送入逻辑运算单元(ALU)去进行计算。其实很简单。只要这两根线控制接下来那部分电路开关即可。 2 接下来的A2和A3,01表示加法,那么就走加法运算那部分电路,关闭减法等运算电路。 3 A4-A7将被送入寄存器电路,从中读取寄存器保存的值。送到ALU的第一个数据接口电路上。 4 后面的A8-A11同样被送入寄存器选择电路,接通R2寄存器,然后R2就把值送出来,放到ALU的第二个数据接口上。 5 ALU开始运算,把两个接口电路上的数据加起来,然后输出。 6 最后结果又被送回R1。 基本上简单的运算计算机就是这么操作的。他其实不知道你那些指令都是什么意思。具体的指令编程机器码后就会变成数字电路的开关信号。其中某几段会作为控制信号,控制其他部分的数据走不同的电路以执行运算。他没有一个地方保存着如何翻译这些机器码的字典,所有机器码的意义都被体现在整个电路的设计中了。 按冯 · 诺依曼存储程序结构体系的思路,一个程序的全部机器码全部保存在内存中(程序指令与数据结构分区保存),内存可以随机访问。在CPU中,由控制器的PC计数器控制顺序从内存中读取指令或数据,由控制器对指令进行译码,产生相应的控制信号由控制电路控制CPU的运算部件和寄存器进行运算和存取操作,直至全部代码执行完成。 |
|
来自: 昵称29894591 > 《计算机》