微机原理_第3章 寻址方式与指令系统

3.1 指令格式与寻址方式

3.1.1 指令格式

计算机通过执行指令来处理各种数据,同时指出执行的操作数据的来源操作结果的去向

指令语句格式:(其中,[]内的是可以省略的,<>内的是不可以省略的

[标号:] <操作码>[操作数],[操作数];[注释]

指令的标号表示一条指令的符号地址,后面必须带有一个冒号,它是一个可选项,一般在程序的入口处设置一个标号。

操作码用助记符表示,表示指令执行什么样的操作(具体内容在本章3.2节会详细说明)。

操作数符号或符号地址表示,指操作数本身、操作数地址或操作结果送到哪里去。

单操作数

举例:
INC AX ;自加1
DEC CX ;自减1

双操作数:源操作数和目的操作数

双操作数指令举例: 操作码 目的操作数,源操作数
例如:
MOV AX,[2000H]
ADD AH,BL

无操作数

例如:HLT、NOP

注释是用于解释程序,由英文分号“;”开头,直至语句的结尾。注释对汇编程序不起作用,不会生成目标代码,只供增强可读性,可忽略

3.1.2 寻址方式【要求:给出指令,指出寻址方式】

所谓寻址方式,就是操作数地址的形成方式,形成操作数地址的过程称为寻址过程。

寻址方式:与数据有关的寻址方式、与转移地址有关的寻址方式

数据寻址方式是针对操作数而言的,因此源操作数和目的操作数的寻址方式可以不同。在说明一条指令的寻址方式时,必须指明是源操作数的寻址方式还是目的操作数的寻址方式。为了理解和举例方便,本节的寻址方式都是针对源操作数而言的。

1.立即寻址方式——Imm(immediate)

操作数直接在指令中给出,作为指令的一部分存放在代码段中,这种操作数称为立即数。

立即数可以是8位或16位的,在80386以上的CPU中,还可以是32位的

举例:
MOV AL, 5
MOV AX, 3064H

主要用于给寄存器赋初值

只能用于SRC(源操作数)字段,不能作目的操作数

SRC 和 DST(目的操作数)的字长一致

举例

微总结:
MOV R,Imm ;R为8位或16位的寄存器
MOV M,Imm ;M为物理地址

2.寄存器寻址方式——寄存器R(R8、R16)、段寄存器SegR

操作数存放在指令指定的8位、16位或32位(暂时不考虑)通用寄存器中。

MOV AX, BX
MOV AL, BH

16位操作数,寄存器可以是AX、BX、CX、DX、SI、DI、SP、BP等

8位操作数,寄存器可以是 AH、AL、BH、BL、CH、CL、DH、DL

举例

为避免指令执行时间过长,双操作数指令一般必须有一个操作数使用寄存器寻址

寄存器寻址常用来存放运算对象、中间结果、运算结果、计数值等。

第1、2种寻址方式与存储器无关、速度快,只在CPU内部执行,不依靠外部总线。

微总结:
MOV R,R/SegR ;R为8位或16位的寄存器,SegR为16位的段寄存器(CS/DS/SS/ES)
MOV M,R/SegR ;M为物理地址
MOV SegR,R ;SegR为16位的段寄存器(CS/DS/SS/ES)

3.直接寻址方式——M

直接寻址指的是操作数在存储器中的有效地址EA直接包含在指令中,书写时有效地址加上中括号

有效地址EA(即:操作数的偏移地址)由指令直接给出,先求操作数的物理地址,再访问存储器取得操作数

举例

(1)如下图所示,物理地址PA = 16 × (DS) + EA = 10H × (DS) + EA,其中,PA为物理地址,DS(SA)为段基址,EA为偏移地址(有效地址)。

(2)如下图所示,部分解析如下

MOV AX,[1000H]

DS段的1000H和1001H两个单元的内容送入AX寄存器中(具体原理如上面的举例),故它也等于:MOV AX,DS:[1000H]

DS段属于数据段,是默认属性;由于是存入AX寄存器,所以是两个单元的内容

MOV EAX, ES:[2000H]

ES段的2000H~2003H四个单元的内容送入EAX寄存器中,其中ES为段超越前缀

EAX为32位寄存器,ES: 则强调其使用ES寄存器

MOV AX, BUF

DS段内以有效地址BUF(符号地址)起始的两个单元的内容送入AX寄存器中

需要在前面定义:BUF DW ? ,这相当于C语言里面的:int BUF

DW: define word,? : 初始化值,可以为具体数据

(3)操作数地址可由变量(符号地址)代替数值地址

微总结:
MOV R,M ;R为8位或16位的寄存器
MOV SegR,M ;SegR为16位的段寄存器(CS/DS/SS/ES)

4.寄存器间接寻址方式

操作数的有效地址EA存放在基址寄存器BX、BP,或变址寄存器SI、DI中,而操作数在存储器中。

如果指定的寄存器是BX、SI、DI,则操作数默认在数据段DS中;如果指定的寄存器是BP,则操作数默认在堆栈段SS中。允许段超越。书写时对间接寻址的寄存器(BX/BP/SI/DI)加上中括号

操作数的物理地址为:(同上文字,得出结论:除非特别指明,除了BP(SS)、IP(CS)之外,基本上其他寄存器(除开AX/CX/DX,因为他们不能存放偏移地址EA)对应的段基址都是DS

物理地址PA = 16 × (DS) + (BX/SI/DI) = 10H × (DS) + (BX/SI/DI)

物理地址PA = 16 × (SS) + (BP) = 10H × (SS) + (BP)

偏移量为16位时,只考虑上述4个寄存器,若为32位,所有通用寄存器都可以用于寄存器间接寻址。

举例

5.寄存器相对寻址方式/直接变址寻址

操作数的有效地址是一个基址寄存器或变址寄存器中存放的数据加上指令中给出的8位或16位偏移量(常用count表示)

其物理地址为:(与寄存器间接寻址方式异曲同工,只不过多了偏移量)

物理地址PA = 16 × (DS) + (BX/SI/DI) = 10H × (DS) + (BX/SI/DI) + 8位或16位偏移量

物理地址PA = 16 × (SS) + (BP) = 10H × (SS) + (BP) + 8位或16位偏移量

实际上就是在寄存器间接寻址的基础上,再加上一个偏移量(适于数组、字符串、表格的处理)

以下三条指令是等效的:
MOV BX, [BP+COUNT]
MOV BX, [BP]+COUNT
MOV BX, COUNT[BP]

举例

说明:
MOV BX, COUNT[BP] 语句是三个等效语句中用得最多的;
除了立即数寻址和寄存器寻址外,其余都是将 源操作数地址所对应的内容送至目的操作数

6.基址变址寻址方式

操作数的有效地址是一个基址寄存器和一个变址寄存器的内容之和

段寄存器一般由基址寄存器决定,使用BX默认段寄存器DS;使用BP,默认段寄存器SS

允许段超越(同“4.寄存器间接寻址方式”)

其物理地址为:(适于数组、字符串、表格的处理)

物理地址PA = 16 × (DS) + (BX)+(SI/DI) = 10H × (DS) + (BX) + (SI/DI)

物理地址PA = 16 × (SS) + (BP) + (SI/DI) = 10H × (SS) + (BP) + (SI/DI)

注意区分寄存器间接寻址方式和基址变址寻址方式
寄存器间接寻址方式:
物理地址PA = 16 × (DS) + (BX/SI/DI) = 10H × (DS) + (BX/SI/DI)
物理地址PA = 16 × (SS) + (BP) = 10H × (SS) + (BP)
基址变址寻址方式:
物理地址PA = 16 × (DS) + (BX)+(SI/DI) = 10H × (DS) + (BX) + (SI/DI)
物理地址PA = 16 × (SS) + (BP) + (SI/DI) = 10H × (SS) + (BP) + (SI/DI)

举例

7.相对基址变址寻址方式

操作数的有效地址是一个基址寄存器和一个变址寄存器的内容和8位或16位位移量之和。当基址寄存器为BX时,用DS为段寄存器,当基址寄存器为BP时,用SS为段寄存器。

物理地址PA = 16 × (DS) + (BX)+(SI/DI) + 8位或16位偏移量 = 10H × (DS) + (BX) + (SI/DI) + 8位或16位偏移量

物理地址PA = 16 × (SS) + (BP) + (SI/DI) + 8位或16位偏移量= 10H × (SS) + (BP) + (SI/DI) + 8位或16位偏移量

举例

总结

源操作数直接作为内容(数据)传至目的操作数

立即寻址方式

MOV R,Imm ;R为8位或16位的寄存器

MOV M,Imm ;M为物理地址

寄存器寻址方式

MOV R,R/SegR ;R为8位或16位的寄存器,SegR为16位的段寄存器(CS/DS/SS/ES)

MOV M,R/SegR ;M为物理地址

MOV SegR,R ;SegR为16位的段寄存器(CS/DS/SS/ES)

源操作数的地址所对应的内容(数据)传至目的操作数

直接寻址方式

MOV R,M ;R为8位或16位的寄存器

MOV SegR,M ;SegR为16位的段寄存器(CS/DS/SS/ES)

寄存器间接寻址方式

物理地址PA = 16 × (DS) + (BX/SI/DI) = 10H × (DS) + (BX/SI/DI)

物理地址PA = 16 × (SS) + (BP) = 10H × (SS) + (BP)

寄存器相对寻址方式/直接变址寻址

物理地址PA = 16 × (DS) + (BX/SI/DI) = 10H × (DS) + (BX/SI/DI) + 8位或16位偏移量

物理地址PA = 16 × (SS) + (BP) = 10H × (SS) + (BP) + 8位或16位偏移量

基址变址寻址方式

物理地址PA = 16 × (DS) + (BX)+(SI/DI) = 10H × (DS) + (BX) + (SI/DI)

物理地址PA = 16 × (SS) + (BP) + (SI/DI) = 10H × (SS) + (BP) + (SI/DI)

相对基址变址寻址方式

物理地址PA = 16 × (DS) + (BX)+(SI/DI) + 8位或16位偏移量 = 10H × (DS) + (BX) + (SI/DI) + 8位或16位偏移量

物理地址PA = 16 × (SS) + (BP) + (SI/DI) + 8位或16位偏移量= 10H × (SS) + (BP) + (SI/DI) + 8位或16位偏移量

3.2 8086指令系统

前言

8086指令系统是80x86的基本指令集,按功能可以把这些指令分为六种类型:数据传送指令、算术运算指令、逻辑运算指令、串操作指令、控制转移指令、处理器控制指令。

部分指令不进行学习,因此只介绍常用的指令。

3.2.1 数据传送指令

数据传送指令用于寄存器、存储单元和输入输出端口之间传送数据或地址。除SAHF和POPF外,对标志无影响。

1.通用数据传送指令:MOV、XCHG、PUSH、POP、 XLAT

基本传送指令MOV(move)

传送指令: MOV DST, SRC

执行操作: (DST) ← (SRC),DST为目的操作数,SRC为源操作数

具体说明:

立即寻址方式
MOV R,Imm ;R为8位或16位的寄存器
MOV M,Imm ;M为物理地址
寄存器寻址方式
MOV R,R/SegR ;R为8位或16位的寄存器,SegR为16位的段寄存器(CS/DS/SS/ES)
MOV M,R/SegR ;M为物理地址
MOV SegR,R ;SegR为16位的段寄存器(CS/DS/SS/ES)
直接寻址方式
MOV R,M ;R为8位或16位的寄存器
MOV SegR,M ;SegR为16位的段寄存器(CS/DS/SS/ES)
总结
MOV R, R/M/SegR/Imm
MOV M, R/SegR/Imm
MOV SegR, R/M

注意事项


交换指令XCHG(exchange)

交换指令: XCHG OPR1, OPR2

执行操作: (OPR1) ←→ (OPR2)

注意:

允许字或字节操作,且不影响标志位

不允许使用段寄存器和立即数

OPR1, OPR2至少有一个是寄存器

XCHG R, M/R
XCHG M, R

CS和IP不能作源opr和目的opr(他们要存放代码段中的下一条要执行的指令存放的实际物理地址)

举例

注意:区分存储数据与存储地址的寄存器


堆栈操作指令PUSH和POP

进栈操作指令PUSH(Push onto the stack )与出栈操作指令POP

在8086系统里,堆栈操作必须以字(即16位二进制数据)为单位,即PUSH/POP R16/M16/SegR

POP R16/M16/SegR(CS除外)

× POP AL (不是16位的操作数)

× POP CS(DST不能是CS,即:CS的值可以压入堆栈,但反过来不能从堆栈中弹出一个值到CS)

进栈是向低地址移动

PUSH R16/M16/SegR

× PUSH AL (不是16位的操作数)

✓ PUSH CS(没有改变CPU数值)

× PUSH 1234H(不能用立即寻址方式)

出栈是向高地址移动

堆栈:

先进后出”的存储区,存在于堆栈段中

在保存和恢复寄存器的内容时,要按对称

次序执行一系列入栈和出栈指令

SP在任何时候都指向栈顶

堆栈指令不影响标志位

举例

上面的与SP有关,因为SP在任何时候都指向栈顶

弹出例题的地址错误,应该是[2FFEB]=C5H,[2FFEC]=3BH


换码指令XLAT(translate)

换码指令:XLAT 或 XLAT OPR

执行操作:(AL) ← [ (BX) + (AL) ]

使用XLAT OPR时,OPR为表格的首地址,提前存入BX寄存器

AL中存入的是表格中的某一项与表格首地址偏移量,所以表格的最大长度不能超过256个字节。

说明:执行指令时,将BX和AL寄存器中的相加,把得到的值作为有效地址,然后将此有效地址所对应的单元的取到AL中,不影响标志位

举例(其中,OFFSET即其对应的首地址,LEA用法见紧挨着的下面内容)


2.地址传送指令: LEA 、LDS 、LES

由于使用强度和篇幅原因,一些使用较少的指令就不过多说明了。

有效地址传送指令LEA(Load Effective Address)

格式:LEA REG, SRC

功能:(REG) ← EA(EA为SRC的偏移地址)

这是一条取有效地址的指令,它用来将源操作数的偏移地址传送到通用寄存器、指针或变址寄存器中

(需要与上面的XTAL指令区分)执行指令时,将BX和AL寄存器中的值相加,把得到的值作为有效地址,然后将此有效地址所对应的单元中的值取到AL中,不影响标志位

举例


3.标志寄存器传送指令:LAHF 、SAHF 、PUSHF 、POPF<略>

4.输入输出指令:IN 、OUT

针对I/O端口

下面介绍中,PORT为端口地址

输入指令(I/O → CPU)

长格式:IN AL/AX, PORT

功能:AL ← [PORT]或AX ← [PORT+1, PORT]

其中,PORT为输入输出端口

短格式:IN AL/AX, DX

功能:AL ← [DX]或AX ← [DX+1, DX]

输出指令(CPU → I/O)

长格式:OUT PORT, AL/AX

功能: [PORT] ← AL或[PORT+1, PORT] ← AX

短格式:OUT DX, AL/AX

功能:[DX] ← AL或[DX+1, XD] ← AX

注意:

CPU只能用累加器AL或AX接收或发送信息

外设共65536个I/O端口,端口号即外设的端口地址(为0000 ~ FFFFH)

前256个端口号00H ~ FFH可直接在指令中指定(长格式)

如果端口号≥ 256,必须端口号 → DX(短格式),再用IN或OUT指令传送信息

不影响标志位

举例

补充:JNZ属于3.2.5 控制指令 中的 条件转移指令,当不相等时(即ZF=0时),进行转移。


3.2.2 算术运算指令

算数运算指令包括加、减、乘、除BCD码调整指令。操作数可以是8为和16为的二进制无符号数或有符号数。

算数运算除了符号扩展指令不影响标志位,INC和DEC指令不影响CF外,其他均不同程度影响标志位。

1.加法指令(ADD/ADC/INC)

不带进位加法指令ADD(add)

格式: ADD DEST, SRC

功能: (DEST) ← (SRC) + (DEST)

只有8位或16位

源操作数SCR保持不变

segR不参与,形式只有5种,即

ADD R, R/M/Imm

ADD M, R/Imm


带进制加法指令ADC(add with carry)

格式: ADC DEST, SRC

功能: (DEST) ← (SRC) + (DEST) + CF

处理多位数据相加时的高位相加

举例

形式同ADD,即

ADC R, R/M/Imm

ADC M, R/Imm


加1指令INC(increment)

格式:INC DEST

功能:DEST ← DEST + 1

形式为:INC R/M

相当于C语言中的i++,通常用于循环

与ADD比较(主要在于CF不同)

除INC指令不影响CF标志外,均对条件标志位有影响。

举例


2.减法指令(SUB/SBB/DEC/NEG/CMP)

不带借位的减法指令SUB(subtract)

格式:SUB DEST, SRC

功能:(DEST) ← (DEST) - (SRC),即DEST为被减数,SRC为减数

形式同ADD/ADC,即

SUB R, R/M/Imm

SUB M, R/Imm


带借位的减法指令SBB(subtract with borrow)

格式:SBB DEST, SRC

功能:(DEST) ← (DEST) - (SRC) - CF,同样需要注意减数SRC被减数DEST

形式同ADD/ADC/SUB,即

SBB R, R/M/Imm

SBB M, R/Imm


减1指令DEC(decrement)

格式:DEC OPR

功能: (OPR) ← (OPR) - 1

形式同INC,即:DEC R/M

对CF不产生影响(INC也是)


求补指令NEG(negtive):

格式:NEG OPR

功能:(OPR) ← 0 - (OPR),相当于求相反数,结果均正确,且计算机中存储的是补码形式

形式同INC/DEC,即:NEG R/M


比较指令CMP(compare)

格式:CMP DEST, SRC

功能:DEST- SRC,比较两个数的大小

形式同ADD/ADC/SUB/SBB,即

CMP R, R/M/Imm

CMP M, R/Imm

比较:与SUB不同的在于结果不送回目的操作数,两个操作数的原值保持不变,只是影响状态标志位。其余同SUB指令。

这条指令后边一般跟条件转移指令(属于3.2.5 控制转移指令),以判断二操作数是否满足某种关系。根据比较结果对标志位的影响来实现程序的分支。

具体判断语句


3.乘法指令(MUL)

无符号数相乘指令 MUL(unsigned multiply)

格式:MUL SRC

功能:

字节操作数 (AX) ← (AL) * (SRC)

字操作数 (DX, AX) ← (AX) * (SRC)

形式与INC/DEC/NEG相同,为 MUL R/M

注意:

目的操作数(隐含操作数)必须为累加器,即字节运算为AL,字运算为AX

两个8位数相乘得到16位乘积存放在AX中,高8位在AH中,低8位在AL

两个16位数相乘得到32位乘积存放在DX、AX中,高16位在DX中,低16位在AX

除CF和OF外,对条件标志位无定义,具体表现如下:在执行MUL指令时,乘积的高一半为0,则(CF)=(OF)=0,否则(CF)=(OF)=1【CF是进位标志,OF是溢出标志】

SRC不能为立即数


4.除法指令(DIV)

无符号数除法指令DIV(unsigned divide)

格式:DIV SRC

功能:

字节操作,即AL ÷ data => AL ... AH

(AL) ← (AX) / (SRC) 的商

(AH) ← (AX) / (SRC) 的余数

字操作,即DX: AX ÷ data => AX ... DX

(AX) ← (DX, AX) / (SRC) 的商

(DX) ← (DX, AX) / (SRC) 的余数

形式与INC/DEC/NEG/MUL相同,为 DIV R/M

注意:

AX(DX,AX)为隐含的被除数寄存器

AL(AX)为隐含的寄存器

AH(DX)为隐含的余数寄存器,若DX=0,也需要写出来

SRC不能为立即数

对所有条件标志位均无定义

尽量避免极大数除以极小数,此时轻则使商溢出,重则无法产生结果

除数为0时,会产生中断

举例【重点是位数


5.BCD码调整指令(DAA/DAS)

BCD码:用二进制编码的十进制数,又称二--十进制数,又称8421码

组合BCD码(压缩BCD码)的调整指令

组合BCD码(又名压缩BCD码),即用8个二进制数表示十进制数的一位

加法的十进制调整指令DAA

格式:DAA

功能:(AL) ← (AL)组合BCD

调整方法:

AF=1或(AL)0~3=A~F,则(AL) ← (AL) + 06H,AF=1

CF=1或(AL)4~7=A~F,则(AL) ← (AL) + 60H,CF=1

减法的十进制调整指令DAS

格式:DAS

功能:(AL) ← (AL)组合BCD

调整方法:

AF=1或(AL)0~3=A~F,则(AL) ← (AL) - 06H,AF=1

CF=1或(AL)4~7=A~F,则(AL) ← (AL) - 60H,CF=1

注意(共同):

(1)隐含的操作寄存器为AL

(2)DAA和DAS紧接在加减法(ADD/ADC,SUB/SBB)指令之后使用

(3)影响条件标志位(对OF无定义)

(4)赋值加‘H’,十六进制

(5)AF为辅助进位标志,CF是进位标志

除了组合BCD码(压缩BCD码)的调整指令,其实还有非组合BCD码的调整指令非组合BCD码乘法调整指令


3.2.3 逻辑运算指令

1.逻辑运算指令:AND、OR、NOT、XOR、TEST

逻辑运算指令主要用于对寄存器或存储器单元中某些位的测试、置位、复位等操作。

逻辑运算指令对操作数都是按进行操作,对相应的标志位产生影响,操作数可以是字节或字

逻辑与指令AND(and)

格式:AND DEST, SRC

执行操作: (DEST) ← (DEST) (SRC)

形式:(同ADD/ADC/SUB/SBB)

AND R, R/M/Imm

AND M, R/Imm

变异功能:

任何位与0相与,其结果为0

任何位与1相与,其结果保持不变

把需要屏蔽的位设为0,其他的位保持不变,能使单元的某些位强迫清0


逻辑或指令OR(or)

格式:OR DEST, SRC

执行操作: (DEST) ← (DEST) (SRC)

形式:(同ADD/ADC/SUB/SBB/AND)

OR R, R/M/Imm

OR M, R/Imm

变异功能:

任何位与0相或,其结果保持不变

任何位与1相或,其结果为1

使某些位置1,其他保持不变


逻辑非指令NOT(not)

格式:NOT DEST

执行操作: (DEST) ← /(DEST),即按位取反, (DEST) + /(DEST) = OFFH

形式:(同INC/DEC/NEG/MUL/DIV)

NOT R/M

注意:

OPR不能为立即数

不影响标志位

注意区分NOT和NEG,NOT是按位取反,NEG是求其补码


逻辑异或指令XOR(exclusive or)

格式:XOR DEST, SRC

执行操作: (DEST) ← (DEST) ⊕ (SRC)

形式:(同ADD/ADC/SUB/SBB/AND/OR)

XOR R, R/M/Imm

XOR M, R/Imm

相同为0,不同为1

变异功能:

任何位与0相异或,其结果保持不变

任何位与1相异或,其结果为1

作用:

①某些位变反,把需变反的位置1。

②用来确定某一个操作数是否与另一个操作数相等


测试TEST(test)

格式:TEST DEST, SRC

执行操作: (DEST) ∧ (SRC),和AND执行同样的指令(但是不产生结果)

形式:(同ADD/ADC/SUB/SBB/AND/OR/XOR)

TEST R, R/M/Imm

TEST M, R/Imm

作用:

测试某位是否为0,把需测试的位置1,只产生状态,不产生结果。

例: TEST AL, 80H 测最高位是否为0,再检查标志位。

**要测试某位是否为1,则可先把该数求反,然后用TEST指令试

注意其与CMP指令进行比较

CMP属于减法指令,结果不送回目的操作数,两个操作数原值不变

AND/OR/XOR注意事项

(CF)=(OF)=0

AF无定义

SF/ZF/PF根据算法结果而定


2.移位指令:SAL、SAR、SHL、SHR

移位指令可以对寄存器或存储器单元按字节或字进行操作

移位指令包括:

算术左移指令SAL(Shift Arithmetic Left)

格式:SAL DEST,COUNT(其中,DEST可以是R/M,COUNT可以是数字1或者CL寄存器

式中COUNT表示移位数,其值或是1,或大于1,当大于1时其值由CL寄存器的值确定

如图,左边表示最高位,右边表示最低位,下同

算术右移指令SAR(Shift Arithmetic Right)

格式:SAR DEST,COUNT(其中,DEST可以是R/M,COUNT可以是数字1或者CL寄存器

其符号位保持不变

逻辑左移指令SHL(Shift Logic Left)

格式:SHL DEST,COUNT(其中,DEST可以是R/M,COUNT可以是数字1或者CL寄存器

逻辑右移指令SHR(Shift Logic Right)

格式:SHR DEST,COUNT(其中,DEST可以是R/M,COUNT可以是数字1或者CL寄存器

算术移位指令适用于带符号数运算 每移动一位,相当于SAL——乘以2,SAR——除以2

逻辑移位指令适用于无符号数运算 每移动一位,相当于SHL——乘以2,SHR——除以2

举例


3.循环移位指令:ROL、ROR、RCL、RCR

功能:循环移位是将目的操作数从一端移出的位返回到另一端形成循环,它可以分成不带进位的循环移位和带进位的循环移位。

循环移位指令包括:

不含进位位的循环左移指令ROL(Rotate Left)

格式:ROL DEST,COUNT(其中,DEST可以是R/M,COUNT可以是数字1或者CL寄存器

式中COUNT表示移位数,其值或是1,或大于1,当大于1时其值由CL寄存器的值确定

如图,左边表示最高位,右边表示最低位,下同

不含进位位的循环右移指令ROR(Rotate Right)

格式:ROR DEST,COUNT

含进位位的循环左移指令RCL(Rotate through CF Left)

格式:RCL DEST,CPUNT

含进位位的循环右移指令RCR(Rotate through CF Right)

格式:RCR DEST,COUNT

所有的循环移位指令不影响SF、ZF、PF、AF。


3.2.4 串操作指令

1.基本串操作指令

前言

基本串操作指令中的源操作数地址DS:SI提供,目的操作数地址ES:DI提供。

源串必须在数据段中,目的串必须在附加段中(数据段和附加段说明请见第4章)。

串操作的方向是递增还是递减由标志位DF确定,DF=1,按递减方向进行;DF=0,按递增方向进行

CLD(Clear DF) DF=0,按递增方向进行

STD(Set DF) DF=1,按递减方向进行

串传送指令MOVS(move string)

格式:

MOVS DEST,SRC ;在操作数中表明是字或字节

MOVSB ;字节传送

((DI))←((SI)), (SI)←(SI)±1,(DI)←(DI) ±1

MOVSW ;字传送

((DI))←((SI)),(SI)←(SI) ±2,(DI)←(DI) ±2

功能:将数据段DS(源操作数地址有DS: SI提供)存储单元的一个字节或字,传送到附加段ES(目的操作数地址有ES: DI提供)存储单元中。

方向标志DF=0时用 +,DF=1时用 - 。 该指令不影响条件码

取串指令LODS(load from string)

格式:

LODS SRC

LODSB ;字节传送,(AL)←((SI)),(SI)←(SI) ±1

LODSW ;字传送,(AX)←((SI)),(SI)←(SI) ±2

功能:将存储器单元源串DS中的一个字节或字内容送入到AL或AX

注意:

LODS指令一般不与REP联用,即LODS指令不能添加重复前缀,因为前面所取的可能会被覆盖

源串必须在数据段中,目的串必须在附加段中,但源串允许使用段跨越前缀来修改

不影响条件标志位

存串指令STOS(store in to string)

格式:

STOS DEST

STOSB ;字节传送,((DI))←(AL),(DI)←(DI) ±1

STOSW ;字传送,((DI))←(AX),(DI)←(DI) ±2

功能:将累加器AL或AX中的内容存入到存储单元的附加段ES中

串比较指令CMPS(compare string)

格式:

CMPS DEST, SRC

CMPSB ;字节传送

((DI))- ((SI)) ,(SI)←(SI)±1,(DI)←(DI)±1

CMPSW ;字传送

((DI))- ((SI)) ,(SI)←(SI)±2,(DI)←(DI)±2

功能:比较源串和目的串是否相同只影响状态标志位,不保留运算结果

串搜索指令SCAS(scan string)

格式:

SCAS 目的串

SCASB ;字节传送,(AL)-((DI)),(DI)←(DI) ±1

SCASW ;字传送, (AX)-((DI)),(DI)←(DI) ±2

功能:将附加段ES存储单元中的一个字节或字内容与AL或AX寄存器中的内容进行比较,不保留运算结果,根据比较结果设置相应的标志位。

注意与上面的“串比较指令CMPS”比较

2.重复前缀指令

无条件重复前缀指令REP (repeat)

格式:REP MOVS/ STOS

功能:REP指令用在MOVS、STOS指令之前,每执行一次串指令,CX←(CX)-1,直到CX=0,重复执行结束

若需重复N次,则使CX=N

条件重复前缀指令REPE/REPZ、REPNE/REPNZ

(1)REPE/REPZ(repeat while equal/zero)

格式:REPE/REPZ CMPS/SCAS

相等/为零则重复

REPE/REPZ指令用在CMPS、SCAS指令之前,每执行一次串指令,CX←(CX)-1,并判断ZF标志位是否为0;只要CX=0或ZF=0,则重复执行结束

(2)REPNE/REPNZ(repear while not equal/not zero)

格式:REPNE/REPNZ CMPS/SCAS

不相等/不为零则重复

REPNE/REPNZ指令用在CMPS、SCAS指令之前,每执行一次串指令,CX←(CX)-1,并判断ZF标志位是否为1;只要CX=0或ZF=1,则重复执行结束

注意:

LODS指令之前不能添加重复前缀

使用串处理指令之前,应该作好如下操作:

(1)源串首地址(末地址)→ SI

(2)目的串首地址(末地址)→ DI

(3)串长度 → CX

(4)建立方向标志(CLD使DF=0,STD使DF=1)

(5)必要时准备好AX,AL


3.2.5 控制转移指令

控制转移指令通过改变CS和IP的内容,实现程序的转移功能。

1.无条件转移指令

格式:JMP DEST

使用标号,不能为保留字

它含有2个段内转移(可以只知道偏移地址),2个段间转移(需要知道段地址和偏移地址),但是不需要掌握

2.条件转移指令

格式:JXX DEST(XX表示不定)

功能:以标志位的状态或者以标志位的逻辑运算结果作为转移依据。如果满足转移条件,则到DEST所指示的指令处执行,否则顺序执行下一条指令,只能使用段内直接寻址8位位移量(-128~127)

(1)根据单个标志位的状态判断转移的指令

这类指令(JC、JNC、JE/JZ、JNE/JNZ、JS、JNS、JO、JNO、JP/HPE、JNP/JPO)如表所示,它们一般适用于测试运算结果,并根据不同的状态标志产生程序分支,以便做不同的处理。

(2)根据两个无符号数的比较结果判断转移的指令

这类指令(JA/JNBE、JAE/JNB、JB/JNAE、JBE/JNA)如表所示,它们根据两个无符号数相比较所产生的状态标志CF和ZF决定是否转移。

a: above b: below n: not e: equal

(3)根据两个有符号数的比较结果判断转移的指令

这类指令(JG/JNLE、JGE/JNL、JL/JNGE、JLE/JNG)如表所示,它们根据两个有符号数相比较所产生的状态标志SF、OF和ZF决定是否转移。【g: greater l: less】

(4)根据CX寄存器的内容判断转移的指令

格式:JCXZ DEST

功能:JCXZ指令不影响CX的内容,此指令在CX=0时,控制转移到目标地址,否则顺序执行JCXZ的下一条指令。


3.循环控制指令

默认以CX寄存器为计数器

格式:

LOOP DEST ;(CX)≠0,则循环

LOOPE/LOOPZ DEST ;ZF=1且CX≠0,则循环

LOOPNE/LOOPNZ DEST ;ZF=0且CX≠0,则循环

功能:

LOOP指令实现CX←(CX)-1,若CX≠0,则继续执行循环,否则顺序执行。

LOOPE/LOOPZ指令实现CX←(CX)-1,若CX≠0且ZF=1,则继续执行循环,否则顺序执行。

LOOPNE/LOOPNZ指令实现CX←(CX)-1,若CX≠0且ZF=0,则继续执行循环,否则顺序执行。

4.过程调用及返回语句

程序设计中,将具有独立功能的程序模块称为子程序,8086汇编中称子程序为过程。

程序执行过程中,由调用程序(主程序)使用调用指令调用这些子程序;当子程序执行后,通过返回指令返回主程序继续执行。

主程序和子程序在同一代码段内属段内调用,否则属段间调用。

调用指令CALL(call)

格式:CALL 过程名

功能:调用已定义的过程,并将断点地址压入堆栈(SS: SP)保存,该指令对状态标志位无影响。

① 段内直接调用

CALL ;SP←(SP)-2,SS:[SP] ←IP;IP←(IP)+16位偏移量

② 段内间接调用

CALL BX   ;SP←(SP)-2,SS:[SP] ←IP;IP←BX

③ 段间直接调用

CALL FAR PTR SUB2

SP←(SP)-2,SS:[SP]←CS;SP←(SP)-2 SS:[SP] ←IP, IP←SUB2偏移地址,CS←SUB2段地址,FAR PTR是段间操作转移符

④ 段间间接调用

CALL FAR PTR [SI]

SP←(SP)-2,SS:[SP]←CS;SP←(SP)-2 SS:[SP] ←IP,IP←[SI,CS←[SI+2]

返回指令RET(return)

格式:RET [n]

功能:放在子程序的末尾,使子程序在功能完成后返回调用程序继续执行,返回地址是调用程序调用子程序时存放在堆栈中的,返回地址出栈送IP寄存器和CS寄存器

① 无参数段内返回 RET ;IP←SS:[SP],SP←(SP)+2

② 有参数段内返回 RET n ;IP←SS:[SP],SP←(SP)+2, SP←(SP)+n

③ 无参数段间返回 RET ;IP←SS:[SP],SP←(SP)+2,CS←SS:[SP],SP←(SP)+2

④ 有参数段间返回 RET n ;IP←SS:[SP],SP←(SP)+2, CS←SS:[SP],SP←(SP)+2,SP←(SP)+n


5.中断指令

中断和过程调用

类似:两者都是将返回地址先压栈,然后转到某个程序去执行

区别:

(1)过程调用转向称为过程的子程序,中断指令是使控制转向中断服务子程序

(2)过程调用可以是NEAR或FAR类型,能直接调用或间接调用,中断调用通常是段间间接转移到服务程序;

(3)过程调用只保护返回地址,中断指令还要保护状态标志进栈

中断指令INT

格式:INT n

功能:用于产生软件中断,以调用中断类型号为n的中断服务程序。n为一个8位立即数,取值范围为0~255

其执行过程为:

①把标志寄存器、INT指令的下一条指令地址的CS值和IP偏移量依次压入堆栈,以保护断点;

②由n×4计算出中断向量,该中断向量中的内容即为中断服务程序的入口地址,将它赋给CS:IP。CPU就转去执行该中断服务程序。

溢出中断指令INTO

格式:INTO

功能:用来判断有符号数加减运算是否溢出。一般把INTO指令安排在有符号数加、减运算指令的后面,一旦查出OF=1。则转到溢出中断处理程序。INTO指令是n=4的INT指令。其中断向量为0010H。

中断返回指令IRET

格式:IRET

功能:将堆栈中的断点地址弹出赋给IP和CS,以实现中断返回;将标志寄存器的值弹出,恢复中断前的状态。


3.2.6 处理器控制指令

1.标志操作指令

格式:

CLC ;CF←0,进位标志位置0(Clear carry)

STC ;CF←1,进位标志位置1(Set carry)

CMC ;CF= 进位标志取反(complement Carry),只有CF可以取反

CLD ;DF←0方向标志位置0(clear direction)

STD ;DF←1方向标志位置1(set direction)

CLI ;IF←0中断允许标志位置0(clear interrupt)

STI ;IF←1中断允许标志位置1(set interrupt)

功能:CLC,CLD,CLI指令分别用于对CF、DF、IF置0;STC、STD、STI指令分别用于对CF、DF、IF置1;CMC用于对CF位取反。

2.外部同步指令

暂停指令HLT

格式:HLT

功能:使CPU处于停机状态,用于等待一次外部中断的产生,中断结束后,继续执行下面的指令

得注意的是,一个实际可运行的用户程序在执行完后,应该返回到DOS提示符状态(简称为返回DOS),简单地用HLT指令使CPU停止运行将无法把控制权交还给DOS操作系统。为了能使程序正常退出并返回DOS,可使用DOS系统功能调用的4CH号功能。

用4CH号功能返回DOS程序段如下:

等待指令

格式:WAIT

功能:该指令在CPU的引脚为高电平时,使CPU处于空转状态,不做任何操作;引脚为低电平时,CPU才脱离空转状态,恢复执行WAIT后面的指令

TEST/连用等待测试【TEST/(23):输入,低电平有效】

空操作指令

格式:NOP

功能:除了使指令指针加1以外,不执行任何操作,可与循环控制指令配合,实现软件延时。

猜你喜欢

转载自blog.csdn.net/qq_59467552/article/details/128556558