[音乐]
通过前面两周的学习,我们了解到高级语言程序的表达是通过运算,
是通过指令来完成的,参加运算的变量或常量就是指令中的操作数,
因此,在了解了数据的表示和运算以后,我们将进一步了解指令, 目前所用的主流计算机基本上都是基于
intel 架构的, 因此,本周我们主要介绍IA-32指令系统,
在介绍IA-32指令系统之前,我们先介绍一下如何 将高级语言程序转换为用机器指令表示的机器代码,
在第一周我们介绍了计算机系统
的概述,我们讲了计算机的硬件基本组成,这样的一个硬件上面
它采用的工作方式是一种存储程序的工作方式,
也就是说所有要计算机完成的任务事先要编写成程序。
然后这个程序呢,要装入到存储器里面,一旦
要执行这个程序计算机就可以把 程序当中的指令一条一条取到这个CPU里面,
自动的来完成,这种叫存储程序的 工作方式,那么程序在执行之前,
它是放在存储器里面的,然后每条指令和每个数据呢,它都有地址,因为是放在存储器
里面的,存储器每个单元都会有一个地址,因此,我们根据地址去取指令和取操作数,
指令要完成的这一个操作要有一个
操作码字段指定,然后指令所要针对的这个操作数,它要有一个地址来
确定这个操作数在哪个地方。
那么,指令的起始地址专门放在一个寄存器里面,这个寄存器我们称为
PC,叫程序计数器PC, 这个指令的执行过程就相当于
是做菜的过程,那么每一个菜谱实际上相当于是一条指令,
因此,我们要去取指令,然后译码,取操作数,执行,回写结果,
然后修改下一条指令的地址,然后放到PC里面,然后继续在
根据PC的内容去取下一条指令,继续这样执行,这个过程实际上就是
指令自动执行的过程,就相当于 我们做一桌子菜,要一道一道菜做一样的,
我们要完成一个程序,我们要一条一条指令执行,所以
指令在整个计算机系统当中,概念是非常重要的,
指令,它实际上和数据,我们刚才讲的都是存放在存储器里面的,
数据我们前面讲过,它是一个0/1序列,都是用二进制的0和1进行编码了的,那么指令同样
它也是一个0/1序列,那么在指令执行过程当中, 指令和数据从存储器要取到CPU
然后存放在CPU的寄存器里面,指令是存放在指令
寄存器里面,数据就存放在专门的通用寄存器里面,
因此,指令当中需要给出这条指令是干什么的,也就是说要给出它的操作性质,
我们称为操作码,还要给出这个指令对谁干什么,
对什么样的操作数进行某种操作,这个如果 操作是个双目运算的话,那么它要给两个源操作数,
如果是单目运算,比如说取反,取负,这种单目运算只要给一个操作数,
那么我们说这个操作数,它要么直接在指令当中给出,它就是一个立即数,
或者是操作数在寄存器里面,那么指令当中直接要给出一个编号,寄存器的编号,
或者这个操作数在存储器的某个单元里面,我们要给出这个存储单元的地址,
这个目的操作数,它要么是存放在
寄存器里面,比如说加出来的结果要么放在寄存器里面,要么存放到存储单元
里面,那么这样的话,指令当中必须给出这个目的操作数的寄存器编号,
或者存储单元的地址,而如果这个源操作数
或者目的操作数是放在存储单元当中的话,
那么,指令当中对这个存储地址的描述,和这个操作数的数据结构是有关系的,
比如说你这个操作数是一个数组的元素,或者是一个 结构的一个分量,对这个操作数地址的描述,
它有相应的一个寻址方式,那么有关这些我们最后详细
介绍指令的时候会介绍,这个地方我们只要知道指令当中,它包含
应该包含这样一些信息,前面我们在第一周里面也
谈到不同层次语言之间的等价关系,讲到任何的高级语言的源程序,
机器是无法直接执行的,它必须通过编译程序,把它翻译成
汇编,比如说汇编指令,然后这个汇编指令进一步要通过汇编程序转换成
机器指令,机器指令是一个0/1序列,那么这样的0/1序列在这个机器
的硬件上面,是可以直接被机器识别,直接理解的,
它直接在机器上执行,执行的结果实际上每条指令会产生
一串控制信号,这些控制信号就控制机器进行相应的动作,而这样来
完成指令,任何高级语言源程序最终是通过执行若干条的指令来完成的,
所以我们可以看出在这个软件和硬件的交界面上面,实际上就
存在着一个接口,这个接口就是指令系统,或者我们叫指令集体系结构,
那么这个里面最关键的就是指令,指令的概念我们前面也大概说了一下,那
我们前面讲的这些指令,实际上是一种机器指令, 它是位于硬件和软件交界面上的,
相当于比如说我们的一个菜谱,指出一个完整的做菜过程,
那么,也就是我们一条指令,指出计算机完成一个完整的基本动作,
所以指令相当于菜谱,后面你们学其它课程的时候,可能还会
碰到一个叫微指令这样的一个概念,那么这个微指令实际上是
硬件范畴,它不是这个交界面上的,它是位于硬件范畴,它是
微程序级的一种命令,相当于什么呢,相当于完成一个菜谱
这个做菜过程当中的一些微过程,洗、 切
煮、 炒等等,这样的一个微过程,那是硬件的范畴,
有些课程的时候还会提到伪指令这样的概念,那么 微指令实际上是由若干个机器指令构成的一个指令序列,
也就是说它是两条以上的指令构成的一个能够完成一个具体功能的一个
指令,只不过我写成一个伪指令来表示,实际上伪指令来
表示的是一个相当于一个子程序,由若干条指令构成的,
因为它是若干条指令构成的一个子程序,所以它是一个软件范畴的东西,那么就相当于是
由多个菜谱合成了一个大菜的这个过程,在这个里面所以我们可以看到机器指令是处在
软件、 硬件交界面上的,后面还会碰到一个汇编指令这样的概念,其实
我们前面已经碰到过了,汇编指令实际上是机器指令的汇编表示形式,
也就是机器指令的一种符号表示,所以机器指令和汇编指令
实际上是一一对应的,从前面一张PPT,我们举的例子也可以看出
一条机器指令对应一条汇编指令,因为机器指令是用
0/1序列表示的,给我们记忆、 书写都比较困难。
所以我们用一种符号表示,所以机器指令和汇编指令都与机器 结构相关,因此,都属于一种叫机器级指令。
不同的机器结构,它的这个是不一样的, 机器指令是一个0/1序列,它是由若干个字段构成,
我们前面讲过,它由操作码字段指出这条指令是干什么的, 然后呢,它还有其它的操作数的
地址或者操作数本身,这样的一些字段, 比如说这样举的一个例子,还有寻址方式这个字段,
指出这个操作数到底是采用立即寻址方式呢,还是
后面这个0/1序列给出来的是寄存器编号,还是储存地址呢,是由这个字段来指出的,
那么不,比如说O/1表示寄存器寻址方式,说明这个是
给寄存器的编号,如果这个操作数是一个直接的一个 立即数的话,那么在某一个字段里面给出一个0/1
01序列指出这个操作数本身,比如说这个地方的,这样的一个 01序列,它实际上是一个补码表示的一个数。
这个数可以是个位移量,也可以是立即数 这个汇编指令实际上是机器指令的符号表示
比如说刚才我们给出来的这样一条机器指令,这样一个01序列
它的汇编形式我们可以写成这样一种形式 那么也就是说,这边的100010这个
六位,实际上指出是一个mov操作,因此我们用mov符号 来表示。
然后后面的这些由汇编导数乘bx+di-6 或者是表述成后面这种形式。
那么也就是说这种符号表示 它可以有不同的形式,比如说这个是给Intel格式,这个是AT&T格式
不管怎么样,这个比01序列更容易识别,更容易看懂
在这个里面,比如说AT&T格式当中,它在这个操作码的 助记符里面,最后有一个长度后缀。
一看到这个长度后缀b,我们就知道
这个后面指令当中指出来的这个操作数的长度是一个字节b,表示一个bite 是一个字节。
这个指令的功能,我们可以用一种语言来描述
比如说这条指令,这条指令,它的功能就是 表示cl这个寄存器的内容
传送到这个地址表示的存储单元当中memory里面
这个地址是[bx]的内容加上[di]寄存器的内容
减6,我们可以看到是这样子的,所以这种语言我们称为寄存器传送级语言 叫RTL。
那么在这个语言当中,我们用R表示寄存器的内容
用M表示存储单元的内容,这是一种语言
当然我们有些时候,还可以用其他的一种 形式来表示。
比如说有些地方是用x加括号 表示地址x中的内容。
比如说这个x等于cl的话
那就表示cl寄存器的内容,这个x等于100的话,就表示存储单元1至100
当中的内容等等。
这个语言的规定 在不同的情况下它有说明
都可以,不管用什么语言、 什么形式来表示 只要能够准确地描述这个指令的功能就可以了
在这个汇编指令当中的mov、 bx、
di movb、 %bx、 %di等等等等都是 助记符,也就是帮助记忆的一种符号
这是汇编语言当中用到的这些助记符
那么我们在第一周的时候介绍过高级语言程序转换成机器代码的过程
那么我们知道任何一个高级语言的源程序它必须经过一系列的
处理转换,最终才能够变成可执行的 这个目标文件。
比如说GCC这个编译器套件 它的这个处理过程先要经过预处理
然后呢,进行编译,就是把预处理以后的这个源程序的文件
编译生成汇编语言源程序 然后再经过汇编这个过程,把汇编语言源程序
通过汇编程序转换成可重定位的机器语言目标代码文件 就是.o文件,就是这样的.o文件
最后一步呢,要通过链接把多个 可重定位的机器语言目标文件以及库例程,比如说printf
链接起来以后,生成最终的可执行的目标文件 [音乐]
[音乐]