指令
1 概述
指令是计算机硬件能够理解和执行的基本命令。这些命令包括算术运算、逻辑运算、数据传送、跳转等操作。
每条指令必须显式或隐式地提供以下信息:
(1)执行的操作
(2)操作数的来源
(3)操作结果的存放处
(4) 下一条指令的地址
示例:

顺序执行时,PC寄存器的长度自动加一(即指令的长度);跳转执行时,指令需要有下一条指令的地址。
一台计算机中所有指令的集合称为该计算机的指令集,也称为指令系统。
2 指令的一般格式

2.1 指令字长



3 地址码

3.1 三地址指令

- 双目运算:有两个操作数参与运算。

3.2 二地址指令

3.2.1 源操作数和目的操作数的位置,有三种类型

存储器指主存。

3.3 一地址指令
第一类:

第二类:
BL寄存器中的数据即A1

3.4 零地址指令
有两类
3.4.1 第一类
指令本身不需要操作数,例如以下x86指令
空指令NOP
等待指令WAIT
停机指令HLT
程序返回指令RET
3.4.2 第二类
指令需要一个操作数,该操作数隐含于CPU内的某个寄存器,例如以下x86指令
用于将加法运算结果调整为压缩BCD,格式的指令DAA
用于将减法运算结果调整为压缩BCD,格式的指令DAS
4 操作码

5 寻址
寻址方式是寻找指令或指令中操作数的有效地址的方式。有效地址可以是主存地址,也可以是虚拟地址(采用虚拟存储器技术)。
寻址方式决定了操作数的存放位置和访问方式。
寻址方式,隐式地包含在操作码字段中或显式地包含在地址码字段中。

寻址方式分为指令寻址和操作数寻址。
5.1 指令寻址
分为顺序寻址和跳跃寻址。
5.1.1 顺序寻址
通常情况下,构成程序的所有机器指令(指令序列)在主存中按顺序存放。大多数情况下,程序按照指令序列顺序执行。
如果知道指令序列中第一条指令的有效地址,在该有效地址的基础上增加一条指令所占用主存单元的数量,就可以得到下一条指令的有效地址。这种寻找指令有效地址的方法就称为指令的顺序寻址。
举例:



5.1.2 跳跃寻址
如果构成程序的指令序列中包含有分支指令或跳转指令,则当程序执行到这种指令时就会改变执行顺序。此时就要采取跳跃寻址。
分支指令通常用于基于条件来改变指令序列的执行顺序。
跳转指令通常用于无条件改变指令序列的执行顺序。
举例:无条件跳转



5.2 操作数寻址
分为:立即寻址、直接寻址、间接寻址、寄存器寻址、寄存器间接寻址、相对寻址、变址寻址、基址寻址、堆栈寻址、其他寻址。
从程序设计角度看,操作数可能是:常数、简单变量、数组和结构体中的某个元素栈(stack)中的数据、外设I/O接口中的状态字或控制字
从指令角度看,操作数的存放位置可能是:CPU内的通用寄存器、主存、IO端口
5.2.1 操作数寻址格式:

5.2.2 立即寻址

5.2.3 直接寻址



5.2.4 寄存器寻址
寄存器寻址方式下,操作数与指令是分开存放的,操作数存放在CPU内的某个通用寄存器中,指令存放在主存中。
指令中的形式地址D,给出的是操作数所在通用地址寄存器的编号。


取指令时,操作数不会随指令一起被读取并送到CPU内的指令寄存器R中。
指令中的形式地址D,给出的是操作数所在通用地址寄存器的编号。
取指令时,操作数不会随指令一起被读取并送到CPU内的指令寄存器IR中。指令执行时,只访问寄存器(而不需要访问主存)。
获取操作数不需要访问主存(从寄存器获取),指令执行速度快。
举例
Intel x86中采用寄存器寻址的指令:
MOV EAX,EBX 将32位通用寄存器EBX中的内容送入32位通用寄存器EAX
5.2.5 间接寻址
间接寻址,指令中的形式地址D,给出的不是操作数的有效地址,而是操作数的间接地址,间接地址所指向的主存单元中的内容才是操作数的有效地址。
取指令时,操作数不会随指令一起被读取并送到CPU内的指令寄存器R中。
指令执行时,需要访问两次主存以获取操作数。

下图给出的是单级间接寻址的示意图,还可有多重间接寻址

间接寻址的特点如下:
能用较短的形式地址D访问较大的主存空间。
当需要修改操作数地址时不再需要改变指令中的形式地址D,只需要修改形式地址D指向的主存单元(存有操作数地址)即可。

举例
某计算机架构中采用间接寻址的指令:
MOV EAX, @5132408H 从主存地址5132408H所指向的存储单元中取出操作数的有效地址,从该地址所指向的存储单元中取出操作数,最后送入32位寄存器EAX
5.2.6 寄存器间接寻址
寄存器间接寻址方式下,操作数与指令是分开存放在主存中的。

指令中的形式地址D,给出的不是操作数的有效地址,而是通用寄存器的编号,而该编号的通用寄存器,其内容就是操作数的主存地址。
取指令时,操作数不会随指令一起被读取并送到CPU内的指令寄存器IR中。指令执行时,需要访问一次主存以获取操作数。

寄存器间接寻址的特点如下:还比间接寻址少访问一次主存。
与寄存器寻址的缺点类似,由于CPU内的寄存器数量有限,因此寄存器间接寻址不能为大量的操作数提供存储其主存地址的服务。
举例
Intel x86中采用寄存器间接寻址的指令:
MOV EAX,[ EBX] 将32位通用寄存器EBX中存储的主存地址所指向主存单元中的内容,送入32位通用寄存器EAX
5.2.7 相对寻址
相对寻址方式下,操作数与指令是分开存放在主存中的。
指令中的形式地址D,是需要给程序计数器PC中的内容加上的偏移量,可正可负(用补码表示),这样就可以形成操作数的主存地址或转移目标地址。
取指令时,操作数不会随指令一起被读取并送到CPU内的指令寄存器IR中。指令译码或执行阶段,会计算操作数的主存地址或转移目标地址。

示例 1 :


取指

译码或执行阶段

得到操作数的主存地址或转移目标地址

示例 2 :
假设某计算机采用定长指令系统,指令字长为16位,其中形式地址D字段为8位,主存按字节编址。若当前指令的主存地址为2024H,采用相对寻址,该相对寻址指令的形式地址D字段的值为6H,则其操作数的主存地址为202cH,

示例 3 :
假设某计算机采用定长指令系统,指令字长为16位,其中形式地址D字段为8位,主存按字节编址。若当前指令的主存地址为2408H,采用相对寻址,而转移后的的主存地址为2402H,则该相对寻址转移指令的形式地址D字段的值为多少?

相对寻址的特点和用途如下:
程序设计时只需给定指令与操作数之间的相对距离,而不必关心操作数在主存中的绝对地址,可用于实现共享代码的浮动。
5.2.8 变址寻址
变址寻址方式下,操作数与指令是分开存放在主存中的。
指令中的寄存器编号n,指明使用CPU内部哪个寄存器(通用寄存器或专用寄存器),来存放变化的地址,该寄存器称为变址寄存器,其内部存放的地址与形式地址D相加,即可得到操作数的主存地址。
取指令时,操作数不会随指令一起被读取并送到CPU内的指令寄存器R中。指令执行时,需要访问一次主存以获取操作数。

变址寻址的特点和用途如下:
变址寄存器n的内容可变,而形式地址D的值设定后在指令执行过程中将保持不变。变址寄存器n的位数大于形式地址D的位数,扩大了寻址范围(可表示整个存储空间)。
主要应用于对数组元素的访问。将数组的首地址赋值给指令中的形式地址D,使变址寄存器n的值按顺序变化,就可以对数组中的各元素进行相同的操作。
举例:
Intel x86中采用变址寻址的指令
MOV EAX,[ESI +32] 将32位通用寄存器ESI中的值加上偏移量32来形成主存地址,再将主存地址所指向主存单元中的内容送入32位通用寄存器EAX
5.2.9 基址寻址
基址寻址中的寄存器编号n是基址寄存器的编号,基址寄存器的值设定好后,其内容保持不变,而形式地址字段,可由用户改变。

对比
变址寻址中的寄存器编号n是变址寄存器的编号,变址寄存器的内容可被用户修改,而形式地址字段的值设定好后,在指令执行的过程中将保持不变。

变址寻址,面向用户
主要用于处理程序循环问题(例如对数组元素的访问),程序执行过程中,用户可以改变变址寄存器的内容来实现指令或操作数的寻址。
基址寻址,面向系统
主要用于程序的重定位。对于多道程序设计,用户编程使用的是虚拟地址,当系统管理程序将用户程序载入主存时,会为每个用户程序分配一个基地址。当某个用户程序运行时,分配给其的基地址被载入基地址寄存器,通过基址寻址方式实现虚拟地址到物理地址的转换。用户通过改变指令中的形式地址D来实现指令或操作数的寻址,而基址寄存器的内容只能由操作系统或系统管理程序通过特权指令设置,对用户透明。
PS:偏移寻址

5.2.10 堆栈寻址
对存放在堆栈中的操作数进行寻址的方法称为堆栈寻址。堆栈一般分为以下两种:
1 寄存器堆栈
在专用寄存器组中划分出来的一块、按“后进先出"(LIFO)规则管理的存储区,也称为硬堆栈。成本较高,不适合做大容量堆栈,较少使用。
2 存储器堆栈
在主存空间中划分出来的一块、按“后进先出”(LIFO)规则管理的存储区,也称为软堆栈。目前计算机普遍采用。
由于存储器堆栈是在主存中划分出来的一块特定存储区,而主存基于地址进行访问,因此,需要使用一个特定的寄存器来记录堆栈中存储单元的地址,该寄存器称为堆栈指针(SP) 。
2.1 存储器堆栈示例:
某计算机中,堆栈指针SP指向栈顶单元,栈向下(即低地址)增长,主存按字节编址,栈操作以字节为单位。
1 空栈,SP指向栈底旁边的那个空位

2 d0要入栈,那么SP减1,这里1指数据宽度

3 d0入栈,SP指向d0的地址

4 以此类推

5 出栈

6 栈顶数据先出栈,然后SP+1

7 全流程展示

5.2.11 其他寻址
将之前介绍的一些寻址方式进行组合,得到复合寻址方式。
复合寻址方式主要用于复杂指令集计算机CISC。
-
相对寻址+间接寻址
- 1 (PC)+D 相对寻址,得到存放操作数有效地址的主存单元的地址
- 2 ( (PC)+D ) 间接寻址,得到操作数的有效地址
-
变址寻址+间接寻址
- 1 (变址寄存器)+D 变址寻址,得到存放操作数有效地址的主存单元的地址
- 2 ( (变址寄存器)+D ) 间接寻址,得到操作数的有效地址
-
间接寻址+变址寻址
- 1 (D) 间接寻址,得到用于变址寻址的偏移量
- 2 (变址寄存器) + (D) 变址寻址,得到操作数的有效地址
5.2.12 操作数寻址汇总

6 指令的操作类型
6.1 数据传送指令
主要完成两个部件之间的数据传送操作。即寄存器与寄存器之间的数据传送,或寄存器与存储器之间的数据传送。
有的计算机采用通用的MOV指令实现数据传送操作。
有的计算机采用LOAD指令从主存单元读取数据到寄存器;采用STORE指令将寄存器中的数据写入主存单元。
数据传送指令可以字节、字、双字为单位进行数据传送。有的指令系统甚至还支持成组数据传送(例如Intel x86的指令系统)。
6.2 算术和逻辑运算指令
-
算术运算:加(ADD)、减(SUB)、乘(MUL)、除(DIV)等逻辑运算:与(AND)、或(OR)、非(NOT)、异或(XOR)等
-
不同架构的计算机对算术运算指令的支持有很大差别。
- 有的计算机仅支持二进制定点数的加、减、比较、求补等最简单的指令,目的是为了让硬件实现最简单。
- 有的计算机除了支持基本的算术运算指令外,还支持浮点运算指令,十进制运算指令,甚至支持乘方、开方、多项式计算等指令。
6.3 移位操作指令
就是用来告诉计算机要执行哪种移位操作,分为:
-
1 逻辑移位指令,移位对象是无符号数
-
2 算术移位指令,移位对象是有符号数
-
3 循环移位指令,移位对象是无符号数
- 3.1 小循环
- 3.1.1 不带CF标志位的循环右移
- 3.1.2 不带CF标志位的循环左移
- 3.2 大循环
- 3.2.1 带CF标志位的循环右移
- 3.2.2 带CF标志位的循环左移
- 3.1 小循环
6.4 程序控制指令
用于控制程序的运行顺序和分支,分为以下几种:转移指令、循环控制指令、子程序调用与返回指令
1 转移指令
- 无条件转移指令
- 条件转移指令
- 一般根据状态标志寄存器(或条件码寄存器)中的相关标志位,来决定是否进行转移操作。
上述标志位一般包括进位标志CF、有符号溢出标志OF、结果为零标志ZF、结果为负标志NF等。
上述这些标志位一般由前面的指令根据执行结果来设置,并作为当前条件转移指令决定是否进行转移的条件。
- 一般根据状态标志寄存器(或条件码寄存器)中的相关标志位,来决定是否进行转移操作。
浙公网安备 33010602011771号