指令系统
程序功能:求两个数据之和并输出
#include<stdio.h>
int main{
int a,b,sum;
a=12;
b=13;
sum=a+b;
printf("sum is %d\n",sum);//在高级语言中称为语句;在机器语言和汇编语言中称为指令。
}
运行结果:sum is 25
基本概念:
- 指令:是计算机硬件能够直接理解并执行的最基本操作。
指令是构成程序的基本元素。 - 指令集或指令系统:一台计算机能执行的机器指令的集合。
一、指令格式设计
1.指令地址码的个数
1.一条指令中必须明显或隐含地包含以下信息:
①操作码。指定操作类型,如:移位、加、减、乘、除、传送等
②源操作数或其地址。指出一个或多个源操作数或其所在的地址,可以是存储单元的地址、寄存器编号或I/O端口,也可在指令中直接给出一个立即数。
③结果的地址。结果所存放的地址,可以是存储单元的地址、寄存器编号或I/O端口。
④下条指令地址。下条指令存放的存储单元的地址。
2.指令的基本格式
3.一条指令由一个操作码和几个地址码构成。
根据指令显式给出的地址个数,指令可分为三地址指令、二地址指令、单地址指令和零地址指令。
2.指令格式设计原则
指令格式的选择应遵循的基本原则:
①指令应尽量短
②要有足够的操作码位数
③操作码的编码必须有唯一的解释
④指令长度应是字节的整数倍
⑤合理选择地址字段的个数
⑥指令应尽量规整。
二、指令系统设计
1.操作数类型
操作数是指令处理的对象,指令涉及到的操作数类型有:
①指针或地址。指针或存储单元地址通常用无符号整数来表示。
②数值数据。数值数据只要是带符号整数和浮点数。
③位、位串、字符和字符串。位和位串数据一般用来表示一些标志、控制和状态等信息。字符和字符串数据用来表示文本、流式文件基本信息等。
④逻辑(布尔)数据。表示逻辑值。
2.寻址方式
操作数存放位置:从指令的角度来看,操作数存放位置可以是CPU中的通用寄存器、存储单元和I/O端口。
有效地址:指令中给出的操作数所在的存储单元的地址。
寻址方式:指令给出操作数或操作数地址的方式。
1.立即寻址
在指令中直接给出操作数本身,这种操作数称为立即数
2.直接寻址
指令中给出的地址码是操作数的有效地址,这种地址称为直接地址或绝对地址。
直接寻址方式下的操作数地址在指令中。
就是在指令中给出的地址码是操作数的有效地址。
3.间接寻址
指令中给出的地址码是存放操作数有效地址的存储单元地址
4.寄存器寻址
指令中给出的是操作数所在的寄存器编号,操作数在寄存器中。
5.寄存器间接寻址
指令中给出的地址码是一个寄存器编号,该寄存器中存放的是操作数的有效地址。
6.变址寻址
变址寻址方式就是指令中的地址码字段给出一个基准地址A(或形式地址)和变址寄存器编号I,操作数的有效地址EA=(I)+A,其中(I)表示变址寄存器I的内容。
例如,8086指令“MOV AL,[SI+1000H]”中的SI为变址器,1000为形式地址,SI的内容加上1000H形成操作数的有效地址。
数组元素的变址寻址:
如图,指令中的地址码A给定数组在存储器中的首地址,变址器I每次自动加或减数组元素的长度。
在按字节编址的情况下,
若每个数组元素为1个字节,则下次变址器I中的内容为(I)± 1;
若每个元素为4个字节,则下次变址器I的内容为(I)±4;
例如,对高级语言语句“for(i=0;i<N;i++){A[i]=...}”,数组元素将沿低地址向高地址方向访问,此时应是自动加;
对应语句“for(i=N-1;i>=0;i--){A[i]=...}”,数组元素将沿高地址向低地址方向访问,此时应自动减。
某些计算机中还允许变址与间指结合使用。
假定指令中给出的变址寄存器为I,形式地址为A,
则先变址后间址时,操作数的有效地址为EA=((I)+A),称为前变址;
先间址后变址时,则EA=(I)+(A),称为后变址。
7.相对寻址
相对寻址方式就是指令中的地址码字段A给出一个偏移量,基准地址隐含由PC给出。即操作数有效地址或转移目标地址EA=(PC)+A。这里的偏移量A是形式地址,操作数的有效地址或转移目标地址可以在当前指令之前或之后,因而偏移量A是一个带符号整数。
操作数有效地址/程序转移地址=PC内容+偏移量
8.基址寻址
基址寻址方式,就是指令中的地址码字段A给出一个偏移量,基准地址可以明显或隐含地由基址寄存器B给出。操作数有效地址EA=(B)+A。
变址、基址和相对三种寻址方式非常类似,都是将某个寄存器的内容与一个形式地址相加来生成操作数的有效地址。通常把它们统称为偏移寻址。
3.操作类型
指令操作类型按功能分为以下几种:
1.算术和逻辑运算指令
2.移位指令
算术左、右移
算术左移:操作数的各位依次向左移,地位补零。有些机器将原操作数的最高位移入进位标志(CF)位,这样,通过判断符号位标志和进位标志是否相等就可以判断是否发生了溢出。
算术右移:各位依次向右移,高位补符号。有些机器将最低位移入进位标志位。
算术左移一位:相当于乘2
算术右移一位:相当于除2
注意:算术移位不能改变符号位
逻辑左、右移
逻辑左移:操作同算术左移,大多数机器一般不再专门设置此指令。
逻辑右移:各位依次向右移,高位补零。有些机器将原操作数最低位移入进位标志位。
大、小循环左、右移
小循环左移:最高位移入进位标志位,同时也移入最低位。
小循环右移:最低位移入进位标志位,同时也移入最高位。
大循环左移:最高位移入进位标志位,而进位标志位移入最低位。
大循环右移:最低位移入进位标志位,而进位标志位移入最高位。
半字交换:寄存器的前半部分和后半部分内容进行交换。
3.传送指令
4.串指令
5.顺序控制指令
顺序控制类指令的功能通过将转移目标地址送到PC中来实现。
①绝对转移:转移目标地址可用直接寻址方式给出
②相对转移:由相对寻址方式给出。有的机器还可以用寄存器寻址方式或寄存器间接寻址方式给出转移目标地址。
③无条件转移指令在任何情况下都执行转移操作。
④条件转移指令(或称分支指令)仅仅在特定条件满足时才执行转移操作。
⑤跳步指令(SKIP)是转移的一种特例,它使PC再增加一个定值。
⑥调用指令也称为转子指令,和转移指令的根本区别在于执行调用指令时必须保存下条指令的地址(称为返回地址)。
⑦返回指令的功能是在被调用过程执行完毕时,将事先保存的返回地址送到PC,这样处理器就能回到原来的调用过程继续执行。
6、CPU控制指令
这类指令由停机、开中断、关中断、系统模式切换以及进入特殊处理程序等指令。大多数机器将这类指令划分为特权指令(也称为管态指令),只能在内核代码执行时使用,以防止因用户使用不当而对系统运行造成危害
7.输入输出指令
4.操作码编码
1.定长操作码编码
指令的操作码部分采用固定长度编码,这种方式译码方便,指令执行速度快,但有信息冗余。
例如,IBM 360/370采用8位定长操作码,最多可有256条指令,但指令系统中只提供了183条指令,有73种冗余编码。
2.扩展操作码编码
扩展操作码编码方式将操作码的编码长度分为几种固定长度的格式。可以采用等长扩展法,例如,按4-8-12、3-6-9这种等步长方式扩展,也可采用不等长扩展法。扩展编码方式的操作码长度不固定,是可变的。
每个地址码为6位,两个地址,则地址码占了6x2=12位
指令为16位,所以操作码占16-12=4位,
针对二地址指令,操作码从 0000 - 1111 有2^4=16种,但二地址指令只有15条,最后的1110没有使用。
1111时,操作码扩展了6位,为单地址,操作码2^6=64,所以操作码有64种,题目中一地址只使用了34条,64-34=30.
剩下的30个地址中,最后的地址位6位,每一种有2的6次方种,30个则有30x26,即零地址指令有30x26条。
5.标志信息的生成与使用
生成的标志位可由专门的条件码寄存器(或称状态寄存器、标志寄存器、程序状态字寄存器)来存放,也可由指定的通用寄存器来存放。
下面的例子中,用通用寄存器r1来存放标志位。
IA-32指令系统中常用条件转移指令的转移条件
6.指令系统设计风格
1.按操作数位置指定风格来分
可分为以下4种不同风格类型的指令系统:
①累加器(Accumulator)型指令系统
②栈(Stack)型指令系统
③通用寄存器(General Purpose Register)型指令系统
④Load/Store型指令系统
2.按指令格式的复杂度来分
分为CISC与RISC两种类型指令系统
①CISC(复杂指令集计算机)风格指令系统
CISC指令系统设计的主要特点如下:
- 指令系统复杂:指令多、寻址方式多、指令格式多。
- 指令周期长:绝大多数指令需要多个时钟周期才能完成。
- 指令周期差距大:各种指令都能访问存储器,使得简单指令和复杂指令所用的时钟周期数相差很大,不利于指令流水线的实现。
- 采用微程序控制:微程序控制器用软件设计思想实现硬件,可以实现对复杂指令的控制。
- 难以进行编译优化:由于编译器可选指令序列增多,使得目标代码组合增加,从而增加了目标代码优化的难度。
②RISC(精简指令集计算机)风格指令系统
RISC指令系统的主要特点如下:
- 指令数目少:只包含使用频度高的简单指令。
- 指令格式规整:寻址方式少、指令格式少、指令长度一致。
- 采用Load/Store型指令设计风格。
- 采用流水线方式执行指令:规整的指令格式有利于采用流水线方式执行,除Load/Store指令外,其他指令都只需一个或小于一个时钟周期就可完成,指令周期短。
- 采用大量通用寄存器:编译器可将变量分配到寄存器中,以减少访存次数。
- 采用硬连线控制器:指令少而规整使得控制器的实现变得简单,可以不用或少用微程序控制。
- 采用优化的编译系统:指令数少有利于编译器的优化。
指令MOV R1,(R2)中包含了哪些寻址方式?简述该指令的操作数的形式过程和功能。
该指令包含有寄存器寻址方式和寄存器间接寻址方式。
通过指令中给定的R2访问R2寄存器,根据R2寄存器的内容去访问存储单元,把存储单元的内容取出来送给R1寄存器。
三、指令系统实例--MIPS指令系统及其汇编语言
1.MIPS指令格式和寻址方式
MIPS是典型的RISC结构,按字节编址,采用32位定长指令字,操作码字段也是固定长度,没有专门的寻址方式字段,由指令格式确定各操作数的寻址方式。
MIPS指令采用三地址指令格式,只有三种类型。如图给出了32位MIPS系统中的指令格式。
R-型指令的两个操作数和结果都存放在寄存器中,其操作码OP为“000000”,操作类型由funct字段指定,
若是双目运算类指令,则寄存器rs和rt的内容分别作为第一和第二源操作数,结果送寄存器rd;
若是移位指令,则对rt的内容进行移位,结果送rd,所移位数由shamt字段给出。R型指令的寻址方式只有一种,就是寄存器直接寻址。
I-型指令是立即数型指令,
若是双目运算类型指令,则将rs的内容和立即数分别作为第一和第二源操作数,结果送rt;
若是Load/Store指令,则将rs的内容和立即数符号扩展后的内容相加作为内存单元地址,Load指令将内存单元内容送rt,Store指令将rt内容送内存单元;
若是条件转移(分支)指令,则对rs和rt内容进行指定的运算,根据运算的结果,决定是否转到转移目标地址处执行转移目标地址通过相对寻址方式得到,即将PC的内容和立即数符号扩展的内容相加得到。由此可知,I-型指令的寻址方式有四种,就是寄存器直接寻址、立即数寻址、相对寻址、基址或变址寻址。
J-型指令主要是无条件跳转指令,指令中给出的是26位直接地址,只要将当前PC的高4位拼上26位直接地址,最后添两个“0”就可以得到32位的跳转目标地址。
J-型指令的寻址方式只有一种,就是变通的直接寻址。
2.MIPS指令中数据的表示
1.MIPS指令中的操作数可以是立即数,或是通用寄存器的内容,也可以是存储单元中的内容。
2.MIPS处理器提供了32个32位通用寄存器,因此寄存器编号占5位。例如,R-型指令格式中的rs、rt、rd和I-型指令格式中的rs、rt都是指通用寄存器。
通用寄存器中,0号寄存器总是为0,31号寄存器用于存放过程调用的返回地址。
5.MIPS中用程序计数器PC指出下条指令的地址。
6.MIPS的存储器按字节编制。对于存储器数据,其操作数地址为32位,通过一个32位寄存器的内容加16位偏移量得到,其中,32位寄存器就是I-型指令中的rs,16位偏移量就是I-型指令中的16位立即数,通常是一个带符号整数。因而,存储器操作数可访问的地址空间大小为2 ^ 32字节
(每个指令占4个字节)
7.MIPS采用大端方式(Big Endian)存放数据,数据要求按字边界对齐。只能通过Load/Store指令访问存储器数据。
8.对于立即操作数,指令中给出的位数为16位,指令执行时,需要将其进行符号扩展或0扩展,变成32位操作数后才能参加运算。
带符号:1111--->11111111
无符号:1111--->00001111
3.MIPS汇编语言
常用5类指令:算术运算、存储访问、逻辑运算、条件分支、无条件转移。
1.运算类指令包括算术运算和逻辑运算指令,
“sub $s1 , $ s2 , $ s3”的含义为“$s1=$s2-$s3”,
I-型格式运算类指令的汇编表示有一个特点,就是指令操作码助记符总是以i结尾,而且第二个源操作数一定是一个立即数。
例如,指令“andi $s1,$s2,100”的含义为“$s1=$s2&100”。
2.逻辑运算指令中还包括了逻辑左移指令sll和逻辑右移指令srl。
例如,指令“srl $s1,$s2,10”的功能为“$s1=$s2>>10”,
其含义为:将寄存器s1中。
逻辑右移操作的实现方式为:低位移出,高位补0。
因此,“逻辑右移10位”的含义是:低10位移出,高位补10个0。
3.存储访问类的指令有两种,一种是装入(Load)指令,另一种是存储(Store)指令。
例如,指令“lw $s1,100($s2)”的含义是,
将存储单元中一个32位数据装入到通用寄存器$s1中,
存储单元的首地址为$s2的内容加上100。
因此,这里$s1、$s2和100分别是I-型格式指令中的rs、rt和16位立即数。
4.条件分支类指令包括条件设置指令(如slt)和分支指令(如beq、bne)。条件设置指令slt用于比较两个寄存器内容的大小,或者将某个寄存器内容与一个立即数比较,前者为R-型格式指令,后者为I-型格式指令。
例如,R-型格式指令"slt $s1,$s2,$s3"用于判断寄存器$s2和$s3内容的大小,若“小于”,则$s1=1,否则$s1=0。
分支指令beq、bne分别用于判断两个寄存器内容是否相等、不等、并根据判断结果确定是否转移到目标指令处执行,它们都是I-型格式指令,转移目标地址采用相对寻址方式,即转移目标地址=(PC)+偏移量,指令中的16位立即数就是偏移量。
5.无条件跳转指令包括j、jal和jr等几条指令。
j指令执行后,将直接跳转到转移目标地址;
jal指令用于过程调用,在执行过程中,将先把当前PC的内容(jal指令下条指令的地址)作为返回地址,保存到31号寄存器ra中取出返回地址,将其作为转移目标地址进行跳转。
四、程序的机器级表示
1.选择结构的机器代码表示
选择结构根据判定条件来控制一些语句是否被执行,例如:有if-then、if-then-else、switch-case、if-goto等选择语句。
对应高级语言中的这些选择语句,在机器语言中提供了各种条件码(标志位)的设置功能以及各种分支(条件转移)指令和无条件转移指令。编译器通过条件设置指令和各类转移指令来实现程序中选择结构语句。
2.循环结构的机器代码表示
循环结构是指可重复执行的一组语句,例如,有while、until、loop:......goto loop等循环语句。分支指令在循环结构中也起重要作用,主要用来判断循环条件是否结束。此外,大多数循环体内需要对数组元素进行处理,因此,需要用到自动变址寻址,如果指令系统不提供自动变址,则编译器需要选用对变址器进行增量的指令来使每次循环按顺序取不同的数组元素。
以下是一个C程序段:
while(i!=k){
x=x+A[i];
i=i+1;
}
假定x、i、k由编译器分别分配给MIPS寄存器$s1,$s2,$s3,
数组A的每个元素为一个32位字,首地址存放在$s5中,
要求给出编译后的MIPS汇编表示