指令系统
8086/8088的指令系统大致可分为以下六种类型:
1,数据传送指令
2,算术运算指令
3,位操作指令
4,串操作指令
5,程序控制指令
6,处理器控制指令
学习指令要掌握三个方面的内容:
1,指令的功能
2,指令的寻址方式
3,指令操作对标志寄存器中状态标志位的影响
汇编语言指令语句格式
由4部分组成:
标号:指令助记符 目的操作数,源操作数 ;注释
1,标号表示该指令在主存中的逻辑地址
2,每个指令助记符就代表一种指令
3,目的和源操作数表示参与操作的对象
4,注释是对该指令或程序段功能的说明
用到的符号意义如下:
- DST:目的操作数
- SRC:源操作数
- OPR:操作数
- MEM:存储器操作数
- REG:寄存器操作数
(16位的AX,BX,CX,DX,BP,SP,SI,DI或
8位的AH,AL,BH,BL,CH,CL,DH,DL) - SEG:段寄存器(16位的CS,DS,ES,SS)
- Data:立即数
- port:8位的端口地址
- DST_ADDR:转移的目标地址
- COUNT:计数器
一,数据传送指令
数据传送类指令将数据、地址或立即数传送到寄存器或存储器单元中。它又可分为通用数据传送指令、累加器专用传送指令、地址传送指令和标志传送指令等四组。
1,通用数据传送指令通用数据类指令都不影响标志位!!!
1)最基本的传送指令MOV
指令格式:
MOV dst,src ;(dst)←(src)
dst 是目的操作数
Src 是源操作数
指令功能:
将源操作数src送给目的操作数dst,本质上是数据的“复制”,源操作数本身不变。
需说明一点,对于代码段寄存器CS和指令指针寄存器IP,通常无需用户利用传送指令改变其中的内容。但是CS可以作为源操作数。
寻址方式:
src可以是data/MEM/REG/SEG
dst可以是MEM/REG/SEG(不能为CS,IP)
说明:
*CS不能做目的操作数;IP不能作为目的寄存器,立即数不能作为目的操作数
*不能MEM<=>MEM,不能SEG<=>SEG,不能SEG<=data
**源操作数和目的操作数类型要一致。
对标志位的影响:
不影响
例:
MOV AL,80H
MOV word ptr [BX],1020H
MOV AX,BX
MOV DH,AL
MOV [BX+10H],DX
MOV DX,[BX+SI]
MOV SS,AX
MOV SS,[1000H]
MOV AX,DS
MOV [3020H],DS
2)堆栈操作指令
堆栈操作指令是用来完成压入和弹出堆栈操作的。
⑴ 压入堆栈指令PUSH(PUSH word onto stack)
指令格式:
PUSH src ;
指令功能:
先将栈顶指针SP减2// (SP) ←(SP)-2
再将源操作数src压入栈中// ((SP)+1:(SP)) ←(src)
⑵ 弹出堆栈指令POP(POP word off stack)
指令格式:
POP dst ;
指令功能:
先将栈顶存储单元内容弹出到操作数dst中// (dst) ←((SP)+1:(SP)),
再将堆栈指针SP加2// (SP) ←(SP)+2
寻址方式:
源操作数src可以是REG/MEM/SEG ,且必须是16位的操作数,但不能是立即数。
目的操作数dst,可以是REG/MEM/SEG(不能是CS) ,且必须是16位的操作数,但不能是立即数。
说明:
*堆栈按后进先出原则组织。
*堆栈操作以字为单位进行。
*目的操作数dst不可以是CS。
*指令中的操作数不能是立即数。
*堆栈指针为SS:SP,SP自动进行+2、-2操作、永远指向栈顶
对标志位的影响:
不影响
例:
PUSH [BX+DI]
PUSH AX
PUSH CS
POP [BX+SI+1020H]
POP BX
POP DS
例:已知(AX)=1020H,(BX)=3040H,分析下面程序段的执行过程。
1
PUSH AX
PUSH BX
POP AX
POP BX
2
PUSH AX
PUSH BX
POP BX
POP AX
3)交换指令XCHG (Exchange)
指令格式:XCHG dst , src
指令功能:
将源操作数和目的操作数进行交换 // dst <=> src
寻址方式:
src和dst均可为REG/MEM,
说明:
* 段寄存器的内容不能参加交换
*不能同时为存储器操作数
*至少有一个是寄存器操作数
*都不能是立即数
对状态位的影响:
不影响
例:
XCHG BX,[BP+SI]XCHG DL,BLXCHG BX,CXXCHG [2000H],AHXCHG [2000H],BX
错误示例:
XCHG AL,BX //操作数的类型要匹配XCHG [BX], [1000H] //不能同时为存储器操作数XCHG AX, SS //不能为段寄存器XCHG AL, 10H //不能为立即数
2,累加器专用指令
这类指令中的一个操作数必须是累加器。累加器操作数可以是8位的,也可以是16位的
1)输入/输出指令
输入输出指令可以分为两大类:一类是直接端口地址的输入/输出指令:一类是通过DX寄存器间接端口地址的输入/输出指令。
a, 输入指令
①直接寻址的输入指令
指令格式:
IN acc, port ; //port<=0FFH
指令功能:
从端口port中直接读取一个字节或一个字送到acc(AL或AX)中。//(acc) ←(port)
②间接寻址的输入指令
指令格式:
IN acc, DX ;
指令功能:
将DX中内容指定的端口地址中的一个字节或字送入acc(AL或AX)中 /
/(acc) ←( (DX) )
注:执行此指令前应将端口的16位地址放入DX中
b, 输出指令
①直接寻址的输出指令
指令格式:
OUT port, acc ; //port<=FFH
指令功能:
将acc(AL或AX)中的一个字节或字送到port指定的端口中,port<=FFH
//(port) ← (acc)
②间接寻址的输出指令
指令格式:
OUT DX, acc ;
指令功能:
将acc(AL或AX)中的一个字节或一个字送入DX中的内容指定的端口中
//((DX)) ← (acc)
2)字节转换指令XLAT(transLATe)
指令格式及操作:
XLAT src_table ;(AL) ←((BX)+(AL))
XLAT指令是用来将一种字节代码转换成另一种字节代码。常用该指令进行查表操作。
使用前先建立一个字节表格,表格的首址存入BX,要转换的代码(即相对于表格首址的位移量)放入AL,然后执行XLAT,在AL中得到转换以后的代码。
XLAT指令还可以有以下几种表示形式:
XLAT ;不写操作数
XLATB ;有B就不允许再写操作数。
XLAT ES:src_table ;重设段寄存器为ES
[例]在内存的数据段有一张16进制数的ASCII码表,其首地址为Hex_table,如下图所示,欲将十六进制数0AH转换成ASCII码,则可用以下几条指令实现:
MOV BX, OFFSET Hex_tale ;(BX) ←表首址
MOV AL, 0AH ;(AL) ←十六进制数A
XLAT Hex_table ;查表转换
3,目标地址传送指令
目标地址传送指令常常用于在串操作时建立初始的地址指针
8086/8088CPU提供了三条将地址指针写入寄存器或寄存器对的指令,他们可以写入近地址指针和远地址指针。
1)取有效地址指令LEA(Load Effective Address)**
指令格式:
LEA reg16, mem
指令功能:
将存放源操作数的16位偏移地址
(即有效地址EA)送到一个16位的通用寄存器中。//(reg)<–OFFEST mem
寻址方式:
源操作数必须是一个存储器操作数,目的操作数必须是一个16位通用寄存器操作数。
例如:
LEA BX, buffer
LEA AX, [BP][DI]
LEA DX, bety[BX][SI]
注意LEA指令和MOV指令的异同,比较下面两组指令:
不同:
LEA BX,buffer ;将存储器buffer的偏
移地址送到BX
MOV BX,buffer ;将存储器buffer的内
容传送到BX
相同:
2)地址指针装入DS指令LDS(Load pointer into DS)
指令格式:
LDS reg16, mem32
指令的功能:
将源操作数所对应的双字长的内存单元中的高字
内容(一般为16位段基址)送入DS,低字
内容(一般为偏移地址)送入指令所指定的寄存器中。
寻址方式:
源操作数必须是一个存储器操作数,目的操作数必须是一个16位通用寄存器操作数。
例如:
LDS DI, [2130H]
3)地址指针装入ES指令LES(Load pointer into ES)
指令格式:
LES reg16, mem32
指令的功能:
将源操作数所对应的双字长的内存单元中的高字
内容(一般为16位段基址)送入ES,低字
内容(一般为偏移地址)送入指令所指定的寄存器中。
寻址方式:
源操作数必须是一个存储器操作数,目的操作数必须是一个16位通用寄存器操作数。
4,标志传送指令
标志传送指令有4条,这些指令均为单字节指令,操作数均为隐含形式。
1)取标志指令
指令格式: LAHF
指令功能:
将标志寄存器FLAGS中的5个状态标志位SF、ZF、AF、PF、CF分别取出传送到累加器AH的对应位。//(AH)<– (FLAGS)
寻址方式:
均为隐含操作数。
对状态位的影响:
对状态位无影响
2)置标志指令
指令格式: SAHF
指令功能:
将AH中的第7、6、4、2、0位分别传送到标志寄存器对应位。标志寄存器FLAGS中的5个状态标志位SF、ZF、AF、PF、CF将会被修改为AH寄存器中对应位的状态,但其余状态标志位如OF、DF、IF、TF不受影响。
//(FLAGS)<–(AH)
寻址方式:
均为隐含操作数。
对状态位的影响:
FLAGS寄存器中的SF、ZF、AF、PF和CF将被修改成AH寄存器对应位大二状态,但其余状态位即OF、DF、IF、TF不受影响。
3)标志压入堆栈指令PUSHF(PUSH Flags onto stack)
指令格式:
PUSHF ;
指令功能:
将标志寄存器的(16位)内容压入堆栈。
//(SP) ←(SP)-2;((SP)+1;(SP)) ←(FLAGS)
对状态位的影响:
不影响标志位。
4)标志弹出堆栈指令POPF(POP Flags off stack)
指令格式:
POPF ;
指令功能:
与PUSHF相反,将的(16位)内容弹出堆栈。
PUSHF指令可用于调用过程中保护当前标志寄存器的值,过程返回时再使用POPF指令恢复标志寄存器原来的值。
//(FLAGS) ←((SP)+1;(SP)),(SP) ←(SP)+2
对状态位的影响:
恢复标志寄存器原来的值
数据传送指令中,SAHF和POPF影响状态标志位,其余均不影响。
二,算术运算指令
1,算术运算的数据类型
2,算术运算指令对标志位的影响
3,二进制运算指令
1)加法指令
a,不带进位加法指令ADD(ADDition)
格式:ADD DST,SRC
操作:
将目的操作数和与源操作数相加,将结果送给目的操作数//DST <= DST+SRC
寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算
对状态位的影响:
全部影响
b,带进位加法指令ADC(ADdiion with Carry)
格式:ADC DST,SRC
操作:将目的操作数和与源操作数相加,再加上进位标志CF,将结果送给目的操作数 //DST <= DST+SRC+CF
寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算
对状态位的影响:
全部影响
c,加1指令(INCrement by 1)
格式:INC DST
操作:将目的操作数加1,结果送回目的操作数 //DST <= DST +1
寻址方式:
DST可以是MEM/REG
不可以是data/SEG
对状态位的影响:
除了CF,其他全部影响
例, 计算两个多字节十六进制数之和:3B74AC60F8H+20D59E36C1H=?
式中被加数和加数均有5个字节,可以编一个循环程序实现以上运算。假设已将被加数和加数分别存入从DATA1和DATA2开始的两个内存区,且均为低位字节在前,高位字节在后,如图4.15所示。要求相加所得结果仍存回以DATA1为首址的内存区。
程序流程图如下图,程序如下:
MOV CX,5 ;设置循环次数MOV SI,0 ;置位移量初值CLC ;清进位CF
LOOPER:MOV AL,DATA2[SI] ;取一个加数ADC DATA1[SI],AL ;和一个被加数相加INC SI ;位移量加1DEC CX ;循环次数减1 JNZ LOOPER ;加完否,若没完,转LOOPER,继续相加HLT ;程序暂停
2)减法指令
a,不带进位减法指令SUB(subtract)
格式:SUB DST,SRC
操作:
将目的操作数减去源操作数,结果送回目的操作数 //DST <= DST-SRC
寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算
对状态位的影响:
全部影响
b,带进位减法指令SBB(subtract with borrow)
格式:SBB DST,SRC
操作:将目的操作数减去源操作数,再减去标志位CF,结果送回目的操作数
//DST <= DST-SRC-CF
寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算
对状态位的影响:
全部影响
c,减1指令DEC(Decrement)
格式:DEC DST
操作: 将目的操作数减1,结果送回目的操作数 //DST <= DST -1
寻址方式:
DST可以是MEM/REG
不可以是data/SEG
对状态位的影响:
除了CF,其他全部影响
d,求补指令NEG(Negate)
格式:NEG DST
操作:将0减去目的操作数,结果送给目的操作数 // DST <= 0-DST
寻址方式:
DST可以是MEM/REG
对状态位的影响:
全部影响
注:利用NEG指令可以得到负数的绝对值
e,比较指令CMP(Compare)
格式:CMP DST,SRC
操作:目的操作数减去源操作数,结果并不送到目的操作数中,因此,执行后,二者内容均保持不变,结果反映在状态标志位上 //DST-SRC
寻址方式:
SRC可以是data/MEM/REG
DST可以是MEM/REG
两者不可同时为MEM
不允许段寄存器参与运算
对状态位的影响:
相当于减法,但不保存结果,仅影响标志。
例1:
内存数据段存放了200个带符号数,首地址为TAB1,要求将各数取绝对值后存入以TAB2为首址的内存区。
由于200个带符号数中可能既有正数,又有负数,因此先要判断正负。如为正数,可以原封不动地传送到另一内存区;如为负数,则需先求补即可得到负数的绝对值,然后再传送。程序如下:
LEA SI,TAB1 ;(SI)←源地址指针LEA DI,TAB2 ;(DI)←目标地址指针MOV CX,200 ;(CX)←循环次数
CHECK: MOV AL,[SI] ;取一个带符号数到ALOR AL,AL ;AL内容不变,只影响标志位JNS NEXT ;若(SF)=0,则转NEXTNEG AL ;否则求补NEXT: MOV [DI],AL ;传送到目标地址INC SI ;源地址加1INC DI ;目标地址加1DEC CX ;循环次数减1JNZ CHECK ;如不等于零,则转CHECKHLT ;停止
例2:
在数据段从myoata开始的存储单元中分别存放两个8位无符号数,试比较他们的大小,并将大者传送到max单元。
LEA BX ,MYDATA ;MYDATA偏移地址送BXMOV AL ,[BX] ;第一个无符号数送AL INC BX ;BX指向第二个无符号数 CMP AL,[BX] ;两个数比较JNC DONE ;若CF=0,则转DONEMOV AL ,[BX] ;否则,第二个无符号数送AL
DONE MOV MAX ,AL ;较大的无符号数送MAX单元HLT ;停止
3)乘法指令
乘法指令具有两个操作数,一个是源操作数,另一个目的操作数是隐含的操作数。
a,无符号乘法指令MUL(Unsigned Multiple)
格式:MUL SRC
操作:两个操作数均按无符号数来处理。
当SRC为8位时,隐含的目的操作数从AL中获得,乘积为16位,放在AX中。
当SRC为16位时,隐含的目的操作数从AX中获得,乘积为32位,放在DX:AX中。
例:
MUL AL ;AL乘AL,结果放在AX中MUL BX ;AX乘BX,结果在DX:AX中MUL BYTE PTR[DI+6] ;AL乘存储器(8位),结果放在AX中MUL WORD PTR ALPHA ;AX乘存储器(16位)结果放在DX:AX中
寻址方式:SRC可以是REG/MEM
对状态位的影响:MUL指令对CF和OF有影响,SF,ZF,AF和PF不确定。
如果运算结果的高半部分(AH或DX中)为0,则(CF)=(DF)=0,若(CF)=(DF)=1,则说明AH或DX中包含着乘积的有效数字。
例:
MOV AL, 14H ;(AL)=14HMOV CL, 05H ;(CL)=05HMUL CL ;(AX)=0064H, (CF)=(OF)=0
本例中的高半部分AH为0,因此(CF)=(DF)=0。
b,带符号数的乘法指令IMUL(Signed Multiple)
格式:IMUL SRC
操作:两个操作数均按有符号数来处理。
当SRC为8位时,隐含的目的操作数从AL中获得,乘积为16位,放在AX中。
当SRC为16位时,隐含的目的操作数从AX中获得,乘积为32位,放在DX:AX中。
寻址方式:SRC可以是REG/MEM
对状态位的影响:MUL指令对CF和OF有影响,SF,ZF,AF和PF不确定。
若乘积的高半部分仅仅是低半部分符号位的扩展,则状态标志位(CF)=(DF)=0,若(CF)=(DF)=1,说明高半部分包含有效数字。
4)除法指令
a,无符号数除法指令DIV(Unsigned divide)
格式:DIV SRC
操作:
1、字节除法:AX/SRC, 商=>AL, 余数=>AH
2、字除法:DX,AX/SRC, 商=>AX, 余数=>DX
b,带符号数除法指令IDIV(Signed divide)
格式:IDIV SRC
操作:类似DIV。
说明:
1、SRC 为 REG/MEM。
2、除法指令影响状态标志但对所有标志无定义。
3、商可能出现溢出,会立即产生除法溢出中断。
5)符号扩展指令
a,字节扩展指令
CBW(Convert byte to word)字节扩展到字
格式:CBW ;如果(AL)<80H,则(AH)?00H,否则(AH)?0FFH
操作:把AL扩展到AX。
b,字扩展指令
CWD(Convert word to double word)字扩展到双字
格式:CWD ;如果(AX)<8000H,则(DX)?0000H,否则(DX)?0FFFFH
操作:把AX扩展到DX,AX 。
说明:
1、CBW和CWD对标志位无影响
2、扩展方法
由符号扩展指令实现,正数补0,负数补1。
(无符号数的扩展:将高位补0)
例:若(AL)=0F2H,执行 CBW 后,(AX)=0FFF2H
4,十进制数(BCD码)运算指令
在微处理器中,没有专用的BCD码运算指令,使用二进制运算指令进行BCD码数的运算后,要用BCD码运算调整指令进行调整,重新得到BCD码的结果。举例如下:
1、34H+29H 按照二进制加法得到的结果是 5DH
2、用调整指令DAA调整成BCD码,规则是
- 低4位>9或AF=1结果加06H;
- 高4位>9或CF=1结果加60H;
3、调整以后得到:5DH + 06H = 63H,这是BCD码运算的结果。
压缩型BCD码的调整指令:
DAA加法调整
DAS减法调整
非压缩格型BCD码的调整指令:
AAA加法调整
AAS减法调整
AAM乘法调整
AAD除法调整
这类指令的操作数隐含为AL或AX
AAA指令的操作为:
如果 (AL) ∧0FH>9 或 (AF)=1
则 (AL) ←(AL)+06H (AH) ←(AH)+1(AF) ← 1(CF) ←(AF)(AL) ←((AL) ∧ 0FH)
否则 (AL) ←((AL) ∧ 0FH)
DAA指令的操作为:
如果 (AL) ∧0FH>9, (AF)=1
则 (AL) ←(AL)+06H (AF) ← 1
如果 (AL) > 9FH 或 (CF)=1
则 (AL) ←(AL)+60H (CF) ← 1
例]要求计算两个十进制数之和,7+8=?。可用以下指令实现:
MOV AX, 0007H ;(AL)=07H,(AH)=00H
MOV BL, 08H ;(BL)=08H
ADD AL, BL ;(AL)=0FH
AAA ;(AL)=05H,(AH)=01H;(CF)=(AF)=1MOV AX, 0007H ;(AL)=07H,(AH)=00H
MOV BL, 08H ;(BL)=08H
ADD AL, BL ;(AL)=0FH
DAA ;(AL)=15H,(AH)=00H ;(CF)=0,(AF)=1
AAS指令的操作为: (非压缩型BCD码调整)
如果 (AL) ∧0FH>9 或 (AF)=1
则 (AL) ←(AL)-06H (AH) ←(AH)-1(AF) ← 1(CF) ←(AF)(AL) ←((AL) ∧ 0FH)
否则 (AL) ←((AL) ∧ 0FH)
DAS指令的操作为: (压缩型BCD码调整)
如果 (AL) ∧0FH>9, (AF)=1
则 (AL) ←(AL)-06H (AF) ← 1
如果 (AL) > 9FH 或 (CF)=1
则 (AL) ←(AL)-60H (CF) ← 1
AAM指令的操作为:(将二进制数转换成十进制数)
(AH)←(AL)/0AH的商;即AL除以10,商送AH
(AL)←(AL)/0AH的余数;即AL除以10,余数送AL
例:要求进行以下十进制乘法运算:7*9=?
解:可编程序段如下
MOV AL,07H ;(AL)=07H
MOV BL,09H ;(BL)=09H
MUL BL ;(AX)=07H?09H=003FH
AAM ;(AH)=06H,(AL)=03H
AAD指令的操作为:(将十进制数转换成二进制数)
(AL)←(AH)?0AH+(AL)(AH)←0
例:要进行以下十进制除法运算:73÷2=?
解:可编程序段如下:
MOV AH,07H ;(AH)=07H,(AL)=03HMOV AL,03H ;(AH)=07H,(AL)=03HMOV BL,02H ;(BL)=02HAAD ;(AL)=49H(即十进制数73)DIV BL ;(AL)=24H(商),(AH)=01H(余数)AAM ;(AH)=03H,(AL)=06H
三,位操作指令
1,逻辑运算指令
说明:TEST相当于AND运算,但是不保存结果,仅影响标志。
常见的用法举例:
⑴ 清进位标志位: AND AX,AX 或 OR AL,AL等。
⑵ 清零操作数:XOR AX,AX 不仅把AX清零,而且也影响了状态标志。
⑶ 把某几位取反:用XOR指令,把要取反的位和1异或,不变的位和0异或。
⑷ 清零或置位某几位:用AND指令清零,用OR指令置位。
2,移位指令
该类指令的使用方法是:
⑴ 移动1位,用类似于 SHL AX,1的格式
⑵ 移动n位,用类似于 SHL AX,CL的格式
说明:
⑴ 逻辑移位适用于无符号数,算术移位适用于有符号数。
⑵ 逻辑左移和算术左移的机器码完全相同,是助记符的两种写法。
3,循环移位指令
ROL循环左移:操作数整体左移,最高位移到CF,同时最高位补原最低位。
ROR循环右移:操作数整体右移,最低位移到CF,同时最低位补原最高位。
RCL带进位的循环左移:操作数整体左移,最高位移到CF,同时CF移到最低位。
RCR带进位的循环右移:操作数整体右移,最低位移到CF,同时CF移到最高位。
使用举例
[例一] 利用循环移位指令可以对寄存器或存储器中的任一位进行测试。如要测试AL寄存器中的第5位的状态是“0”还是“1”,则可利用以下指令实现:
MOV CL,5 ;(CL)?移位次数ROR AL,CL ;(CF)?AL的第5位JNC ZERO ;若(CF)=0,转ZERO……………… ? ;否则?ZERO: …………??
[例二]利用带进位循环移位指令可以实现将两个以上寄存器或存储器单元组合起来一起移位。如DX和AX两个寄存器组成的32位数乘以2,可用以下两条指令实现:
SHL AX,1 ;AX左移1位,(CF)?AX的最高位
RCL DX,1 ;DX带进位左移1位,DX的最低位?(CF)
具体操作如下图:、
四,串操作指令
串操作指令的特征是对数据块(字符串或数值串)进行操作,并且其中部分指令可以两个操作数同时是存储器操作数。
MOVS (Move string) 串传送
CMPS (Compare string) 串比较
SCAS (Scan string) 串扫描
LODS (Load from string) 从串中取数据
STOS (Store in to string) 存数据到串中
说明:
⑴ 串操作指令每次执行完成一个字节或一个字的操作。
⑵ 通常使用重复前缀,用来完成数据块的操作。
重复前缀
⑴ REP 重复
⑵ REPE/REPZ 相等/为零则重复
⑶ REPNE/REPNZ 不相等/不为零则重复
特点:
⑴ 串操作指令需要指明每次操作的类型:B 字节,W字
例如:MOVSB, CMPSW等。
⑵ 串操作指令使用DS:SI作为源操作数的指针;ES:DI作为目的操作数的指针
⑶ 使用DF来表示每次操作以后变址寄存器SI和DI的变化方向
CLD ;DF=0 SI,DI做增量变化 B:+1或W:+2
STD ;DF=1 SI,DI做减量变化 B:-1或W:-2
⑷ 使用CX来表示用重复前缀以后指令需要重复执行的次数
1,串传送指令MOVS(MOVe String)
MOVSB 或 MOVSW 以字节或字为单位在存储单元之间传送数据
可以使用REP前缀
例:教材P132例4.10
2,串装入指令LODS(LOaD String)
LODSB 或 LODSW 从内存中取出字节或字到累加器AL或AX
可以使用REP前缀,但意义不大。
例:教材P133例4.11
3,串送存指令STOS(STOre String)
STOSB 或 STOSW 从累加器中存字节或字到存储器
可以使用REP前缀
例:教材P133例4.12
教材P134例4.13
4,串比较指令CMPS(CoMPare String)
⑷ CMPS指令
CMPSB 或 CMPSW 以字节或字为单位进行两个存储器操作数的比较
可以使用REPE/REPZ、REPNE/REPNZ前缀
用源操作数-目的操作数
例:教材P135例4.14
5,串扫描指令SCAS(SCAn String)
SCASB 或 SCASW 在数据串中查找AL或AX中的内容。
可以使用REPE/REPZ、REPNE/REPNZ前缀
例: 教材P135例4.15
五,程序控制指令
能够使程序的执行流程发生改变的指令
1,转移指令
1)无条件转移JMP
有以下几种类型操作:
⑴ 段内直接短转移
格式: JMP SHORT opr
操作: (IP)←(IP) + Data8 //Data8是一个字节的补码数 范围:-128?+127
⑵ 段内直接近转移
格式: JMP NEAR PTR opr
操作:(IP)←(IP)+Data16 //Data16是两个字节的补码数 范围:-32768 ? +32767
⑶ 段内间接转移
格式: JMP WORD PTR opr
操作: (IP)←寄存器或存储器操作数
⑷ 段间直接转移
格式:JMP FAR PTR opr
操作:指令中用立即数的形式指出目标位置的段地址和偏移量
⑸ 段间间接转移
格式: JMP DWORD PTR opr
操作:目标位置的段地址和偏移量保存在存储器中。
说明:
① 在汇编语言中通常使用标号表示要转移到的位置。
② 使用该指令,可以使程序流程改变到任何目标位置。
2)条件转移JCC
根据判断条件是否成立决定是否转移。按照判断条件的不同分为以下类型:单个标志、无符号数判断、有符号数判断、CX寄存器。
条件转移都是段内直接短转移,即(IP)=(IP)+Data8类型的转移。
指令格式:Jcc short_label
“cc”表示条件
⑴ 判断单个标志
ZF: JZ(JE),JNZ(JNE)
SF: JS,JNS
OF: JO,JNO
PF: JP,JNP
CF: JC,JNC
⑵ 判断无符号数的大小
助记符中的意义: A:大于,B:小于,E:等于
JB(JNAE),JNB(JAE)同JC,JNC,
JBE(JNA),JNBE(JA): 判断CF and ZF
⑶ 判断有符号数的大小
助记符中的意义: G:大于,L:小于,E:等于
JL(JNGE): (SF) ? (OF) 且 (ZF)=0
JNL(JGE): (SF)= (OF)
JLE(JNG): (SF) ? (OF) 或 (ZF)=1
JNLE(JG): (SF)= (OF) 且 (ZF)=0
使用比较大小的指令时,必须区分是有符号数还是无符号数。
⑷ 判断CX寄存器
JCXZ: CX=0
2,循环控制指令
循环指令的转移也都是段内直接短转移,即(IP)←(IP)+Data8类型的转移。
LOOP 循环
判断CX是否等于零,不等于零则循环
LOOPZ(LOOPE) 当为零或相等时循环
判断CX是否等于零,不等于零且ZF=1则循环
LOOPNZ(LOOPNE) 当不为零或不相等时循环
判断CX是否等于零,不等于零且ZF=0则循环
说明:
① 循环指令不影响状态标志。
② 如果目标位置的位移量超出Data8所能够表示的范围,则需要用JMP辅助来完成循环。
3,过程调用与返回指令
如果有一段程序在不同的地方反复出现,则可以将这些程序设计称为过程,相当于子程序,当需要时即可调用。
1)过程调用指令CALL(Call a procedure)
说明:由汇编程序自动匹配为某种寻址方式。
RET 子程序返回指令
用法:RET
段内返回:(IP)←((SP)+1:(SP)),(SP)←(SP)+2
段间返回:(IP)←((SP)+1:(SP)),(SP)←(SP)+2,
(CS)←((SP)+1:(SP)),(SP)←(SP)+2
汇编程序自动匹配为段内或段间的返回
格式:RET Data16
操作:在RET的基础上,把SP再加上一个字数据:
(SP)←(SP)+data16
注意:
一般data16应该是一个偶数,表示堆栈指针向下移动的字节数。这是因为堆栈操作都是字操作。
4,中断指令
将在第七章中进行讨论。