第四章 指令系统

在这里插入图片描述

指令格式

指令

指令又称机器指令,是指计算机执行某种操作的命令,是计算机运行的最小功能单位,一台计算机的所有指令的集合构成该机的指令系统,也称指令集。
一条指令就是机器语言的一个语句,它是一组有意义的二进制代码。
一条指令通常包括操作码字段和地址码字段两部分。在这里插入图片描述

按地址码数分类

零地址指令
不需要操作数,如空操作,停机,关中断指令;
堆栈计算机,两个操作数隐含存放在栈顶和次栈顶,计算结果压回栈顶。
在这里插入图片描述

一地址指令
只需要单操作数,如+1、-1、取反、求补等。
需要两个操作数,但其中一个操作数隐含在某个寄存器。
在这里插入图片描述

二地址指令
常用于需要两个操作数的算术运算、逻辑运算相关指令。
完成一条指令需要访存4次:取指–>读A1–>读A2–>写A1
在这里插入图片描述

三地址指令
常用于需要两个操作数的算术运算、逻辑运算相关指令。
完成一条指令需要访存4次:取指–>读A1–>读A2–>写A3
在这里插入图片描述

四地址指令
A4是下一条将要执行指令的地址,访存4次。
正常情况下取指令之后PC+1,指向下一条指令,四地址指令在执行指令就,将PC值修改为A4所指地址。
在这里插入图片描述
地址码位数的影响
n位地址码的直接寻址范围=2n,若指令长度固定不变,则地址码数越多,寻址能力越差。

按指令长度分类

指令字长:一条指令的总长度(可能会变);
机器字长:CPU进行一次整数运算所能处理的二进制数据的位数,通常和ALU直接相关。
存储字长:一个存储单元中的二进制代码位数,通常和MDR位数相同。

半字指令、单字指令、双字指令都是只指令长度是机器字长的多少倍。

指令字长会影响取指令所需时间。如机器字长=存储字长=16bit,则取一条双指令字长指令需要两次访存。

定长指令字结构
指令系统中所有指令的长度都相等

变长指令字结构
指令系统中各指令的长度不等

按操作码长度分类

定长操作码
指令系统中所有指令的操作码长度都相同。
控制器的译码电路设计简单,但灵活性较低 。

可变长操作码
指令系统中各指令的操作码长度可变。
控制器的译码电路设计复杂,但灵活性较高。

按操作类型分类

数据传送类
进行主存与CPU之间的数据传送。
LOAD:把存储器中的数据存放到寄存器中
STORE:把寄存器中的数据存放到存储器中

运算类
算术运算:加、减、乘、除、+1、-1、求补、浮点运算、十进制运算
逻辑运算:与、或、非、异或、位操作、位测试、位清除、位求反
移位:算术移位、逻辑移位、循环移位。

程序控制类
改变程序的执行顺序
无条件转移JMP
条件转移,JZ:结果为0,JO:结果溢出。JC:结果有进位
调用和返回CALL和RETURE
陷阱Trap和陷阱指令

输入输出类
进行CPU和I/O设备之间的数据传送

扩展操作码指令格式

定长指令字结构+可变长操作码
若指令字长度为16位,每个地址码占4位。则前4位为操作码OP,另有3个4位长的地址码,若4位基本操作码全部用于三地址指令,则有16条,但至少须将1111留作扩展操作码之用,即三地址指令为15条。以此类推,二地址指令为1条,操作码8位;一地址指令15条,操作码12位;零地址指令16条,操作码16位。

在设计扩展操作码指令格式时。需注意:不允许短码是长码的前缀;各指令的操作码不能重复。通常情况下,对使用频率高的指令,分配较短的操作码;对使用频率较低的指令,分配较长的操作码,从而尽可能减少指令译码和分析的时间。

若指令字长固定为16位
在这里插入图片描述
上一层留出m种状态,下一层可扩展出m*2n种状态。

寻址方式

指令寻址

确定下一条要执行的指令的存放地址,由程序计数器PC指明。

顺序寻址
(PC)+“1”—>PC,“1”理解为1个指令字长。

跳跃寻址
执行转换类指令导致的PC值改变。

注:每一条指令的执行都分为“取指令”和“执行指令”两个阶段。

数据寻址

确定本条指令的地址码指明的真实地址。
在这里插入图片描述
直接寻址
指令字中的形式地址A就是操作数的真实地址EA,EA=A。
取值访存1次,执行指令访存1次,共访存2次。
优点:简单,执行指令阶段仅访问1次主存,不需要专门计算操作数的地址。
缺点:A的位数决定了该指令操作数的寻址范围。操作数的地址不易修改。

间接寻址
指令的地址字段给出的形式地址不是操作数的真实地址,而是操作数的有效地址所在的存储单元的地址,即EA=(A)。
优点:可扩大寻址范围,便于编制程序(方便的完成子程序返回)
缺点:指令在执行阶段多次访存(一次间接地址需要两次访存,多次寻址需根据存储字的最高位确定几次访存)。

寄存器寻址
在指令字段中直接给出操作数所在的寄存器编号,即EA=Ri,其操作数在由Ri所指的寄存器中。取指令访存1次,执行指令访存0次,共访存1次。
优点:指令执行阶段不访问主存,之访问寄存器,指令字短且执行速度快,支持向量/矩阵运算。
缺点:寄存器价格贵且个数有限。

寄存器间接寻址
寄存器Ri中给出的不是一个操作数,而是操作数所在单元的地址。取指令访存1次,执行指令访存1次,共访存2次。
特点:与一般间接寻址相比速度更快,但指令的执行阶段需访问主存。

隐含寻址
不是明显的给出操作数的地址,而是在指令中隐含着操作数的地址。
优点:有利于缩短指令字长。
缺点:需附加存储操作数或隐含地址的硬件。

立即寻址
形式地址A就是操作数本身,又称为立即数,一般采用补码形式。
取指令访存1次,执行指令访存0次,共访存1次。
优点:指令执行阶段不访问主存,指令执行时间最短。
缺点:A的位数限制了立即数的范围。采用补码时-2n-1~2n-1-1

偏移寻址
基址寻址:
将CPU中基址寄存器BR的内容加上指令格式中的形式地址A而形成操作数的有效地址,即EA=(BR)+A。要在指令中指明哪个通用寄存器作为基地址寄存器使用。
优点:便于程序“浮动”,方便实现多道程序并发执行,用户不必考虑自己的程序存于主存的哪一空间区域;可扩大寻址范围。
基地址寄存器是面向操作系统的,其内容由操作系统或管理程序确定。在程序执行过程中,基地址寄存器的内容(作为基地址)不变,形式地址A可变(作为偏移量)。

变址寻址:
有效地址EA=A+变址寄存器IX的内容
IX可为专用变址寄存器,也可用通用寄存器作为变址寄存器。变址寄存器是面向用户的,在程序执行过程中,变址寄存器的内容可由用户改变(IX作为偏移量),形式地址A不变(作为基地址)。
优点:在数组处理过程中,可设定A为数组的首地址,不断改变IX中的内容,便可很容易形成数组中任一数据的地址,适于编制循环程序。

相对寻址:
程序计数器PC的内容+A
A是相对于PC所指地址的位移量,可正可负,补码表示。
优点:代码在程序内浮动时不用更改跳转指令的地址码,多用于转移指令。

堆栈寻址
操作数放在堆栈中,隐含使用堆栈指针(SP)作为操作数地址。硬堆栈不访存,软堆栈访存1次。

程序的机器代码表示

x86汇编语言指令基础

指令的作用:改变程序执行流;数据处理;
指令格式:操作码+地址码

//以move指令为例:move 目的操作数d,源操作数5
move eax,ebx; //将寄存器ebx的值复制到寄存器eax
move eax,5; //将5复制到寄存器eax
move eax,dword ptr[af996h]; //将内存地址af996h所指的32bit值复制到eax
move byte ptr[af996h]; //将立即数5复制到内存地址af996h所指的一字节中

指明内存的读写长度:dword ptr—双字32bit;word ptr—单字16bit;byte—ptr字节8bit
x86架构CPU中的寄存器(每个寄存器都是32bit):通用寄存器EAX,EBX,ECX,EDX;变址寄存器ESI,EDI,用于线性表,字符串的处理);堆栈寄存器EBP(堆栈基指针),ESP(堆栈顶指针),用于实现函数调用。

常用的x86汇编指令

//算术运算:
add d,s; //加add,计算d+s,结果存入d
sub d,s; //减substract 计算d-s,结果存入d
mul d,s; //乘multiply 无符号数d*s,乘积存入d
imul d,s; //有符号数d*s,乘积存入s
div d,s; //除divide 无符号数除法edx;eax/s,商存入eax,余数存入edx
idiv d,s; //有符号数
neg d; //取负数negative 将d取负数,结果存入d
inc d; //自增increase 将d++,结果存入d
dec d; //自减decrease 将d--,结果存入d
//目的操作数不可以是常量


//逻辑运算:
and d,s; //与and,将d,s逐位相与,结果放回d。有0则0,全1为1。
or d,s; //或or,将d,s逐位相或,结果放回d。有1则1,全0为0.
not d; //非not,将d逐位取反,结果放回d
xor d,s; //异或exclusive or,将d,s逐位异或,相同为0,不同为1。
shl d,s; //左移shift left,将d左移s位,结果放回d
shr d,s; //右移shift right,将d右移s位,结果放回d

AT&T格式 VS Intel格式
目的操作数d,源操作数s:源操作数在左,目的操作数在右;
寄存器表示:寄存器名之前加“%”,如move %ebx,%eax;
立即数的表示:立即数之前加“$”;
主存地址的表示:用“()”;
读写长度表示:指令后加b,w,l分别表示byte,word,dword,例moveb,movew;
主存地址偏移量的表示:偏移量(基地址,变址,比例因子)

选择语句机器级表示

无条件转移指令jmp

jmp <地址>; //PC无条件转移至地址
jmp 128; //<地址>可以用常数给出
jmp eax; //<地址>可以来自寄存器
jmp [999]; //<地址>可以来自于主存
jmp next; //<地址>可以用“标号”锚定,名字自己取

条件转移指令cmp(compare)

cmp a,b; //比较a和b
je <地址>; //jump when equal 若a=b,则跳转
jne <地址>; //jump when not equal 若a!=b,则跳转
jg <地址>; //jump when greater than 若a>b,则跳转
jge <地址>; //jump when greater equal 若a>=b,则跳转
jl <地址>; //jump when less than 若a<b,则跳转
jle <地址>; //jump when less equal 若a<=b,则跳转

循环语句的机器表示

用条件转移指令实现循环
4个部分构成:循环前的初始化;是否直接跳过循环;循环主体;是否继续循环

用loop指令实现循环

move ecx,500; //用ecx作为循环计数器
looptop: //循环的开始
...
loop looptop; //ecx--,若ecx!=0,则跳转到looptop

//loop looptop等价于
dec ecx;
cmp exc,0;
jne looptop;

函数调用的机器级表示

函数的栈帧:保存函数大括号内定义的局部变量,保存函数调用相关的信息。

函数调用指令:call <函数名>
作用:将IP旧值压栈保存(保存在函数的栈帧顶部);设置IP新值,无条件转移至被调用函数的第一条指令。

函数返回指令:ret
作用:从函数的栈帧顶部找到IP旧值,将其出栈并恢复IP寄存器。

访问栈帧数据
标记栈帧范围:EBP,ESP寄存器
push,pop命令:实现入栈,出栈操作,x86默认以4字节为单位。push先让esp-4再入栈;pop出栈esp+4。

mov指令:用mov指令,结合esp,ebp指针访问栈帧数据。用加法/减法指令,即add/sub修改栈顶指针esp的值。

切换栈帧
函数调用时:

push ebp; //保存上一层函数的栈帧基址(ebp旧值)
mov ebp,esp; //设置当前函数的栈帧基址(ebp新值)

函数返回时:

mov esp,ebp; //让esp指向栈帧的底部
pop ebp; //让esp所指元素出栈,写入寄存器ebp

访问栈帧内数据
访问当前函数的局部变量:[ebp-4][ebp-8]…
访问上一层函数传过来的参数:[ebp+8][ebp+12]…

栈内包含的内容
自底向顶:①上一层帧的基地址(ebp旧值);②若干个局部变量;③未使用区;④部分寄存器值;⑤若干个参数调用;⑥返回地址(ip旧值)

CISC和RISC

复杂指令集计算机 VS 精简指令集计算机
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值