3、 约定操作数事先存放在存储器中存放数据的某个单元,称为存储器操作数。
立即数寻址:立即数只能作为源操作数,不能作为目的操作数。
寄存器寻址:是指操作数就在CPU的内部寄存器中,那么寄存器名课在指令中指出。
CS和IP不可直接由指令修改,exp:MOV AX,CS——正确;MOV CS,BX——错误;MOV AX,IP——错误
在一条指令中,可以对源操作数采用寄存器寻址,也可以对目的操作数进行寄存器寻址,还可以两者都用寄存器寻址方式。
采用寄存器寻址方式的指令在执行时,操作就在CPU内部进行,而不需要访问存储器,因而速度很快。
存储器寻址:用存储器寻址的指令,操作数一般位于代码段之外的数据段、堆栈段或附加段的存储器中,指令中给出的是存储器单元的地址或生成存储器单元地址的信息。 物理地址(PA)=(段寄存器)x 16 + 有效地址(EA)
一条指令中,只能有一个存储器操作数,或者源操作数,或者目的操作数。存储器寻址分为直接寻址、寄存器间接寻址、基址寻址、变址寻址、基址加变址寻址。
1、 直接寻址:操作数在存储器中,存储单元的有效地址由指令直接指出。直接寻址,是在指令的操作码后直接给出操作数的16位偏移地址,因而直接寻址是对存储器进行访问时可采用的最简单的方式。 2、 寄存器间接寻址:PA=16 x(DS)+ EA 3、 寄存器相对寻址: 4、 基址变址寻址:
5、 相对基址变址寻址:
I/O端口寻址
8086采用独立编址的I/O端口,用专门的输入输出指令(IN/OUT)对I/O端口进行操作。当端口编号小于255时,可以直接寻址;大于255时,只能用DX作为间接寻址。
1、 直接端口寻址:
Exp:IN AL,60H;将60H端口中的数据输入到AL中;
IN AX,80H;将80H与81H相邻两端口的16位数据输入到AX中; IN/OUT指令不支持立即数寻址,所以指令中出现的数据是直接寻址的端口地址,不是立即数。
2、 寄存器的间接端口寻址: Exp:MOV DX,333H; 将端口地址送入DX OUT DX,AL; 将AL中的数据输出到DX所指的端口中 MOV DX,330H; 将端口地址送入DX IN AL,DX; 将DX所指的端口中的数据输入到AL中 只能用DX作为I/O指令的间接寻址寄存器,不能用其他寄存器作为I/O指令的间接寻址。
8086 CPU的指令按功能可分为:数据传送、算术运算、逻辑运算和移位、串操作、控制转移和处理器控制指令6种。
数据传送指令:
通用数据传送指令:MOV;格式:MOV dst,src
数据交换指令:XCHG; 格式:XCHG dst,src;1)源操作数与目的操作数不能同时为内存单元;2)不能使用CS、IP作为操作数;3)不影响标志位。
堆栈操作指令:PUSH、POP,在调用子程序时要保存返回地址;在中断处理过程中要保存断点地址;进入子程序和中断处理后还要保留通用寄存器的值;子程序执行完毕和中断处理完毕返回时,又要恢复通用寄存器的值,并分别将返回地址或断点地址恢复到指令指针寄存器中。
1)8086的堆栈操作都是字(16位)操作,不允许字节的堆栈操作,因此PUSH AH是错误的。
2)堆栈指令中的操作数只能是存储器或寄存器操作数,而不能是立即数。 3)堆栈操作指令中,有一个操作数是隐含的,这就是堆栈指针SP只是的栈顶存储单元。
4)入栈时“先减后压”(SP先减2,在压入操作数),出栈时“先弹后加”(弹出操作数后,SP加2)。
5)CS寄存器可以入栈,而出栈指令POP CS却是非法指令。因为8086 CPU指令系统不允许CS寄存器目的操作数。执行POP CS将改变代码段寄存器CS的内容,会导致CPU从一个与程序无关的新段中去取下一条指令,从而使程序错误地运行。
累加器专用传送指令:XLAT、IN、OUT。
XLAT:换码指令,不影响标志位,也称为查表指令。查表结果送入“AL”。 8086系统的I/O指令中有:直接寻址和寄存器间接寻址两种寻址方式,只能用累加器AL/AX与I/O端口进行数据传送。
地址传送指令:LEA、LDS、LES。
LEA:取有效地址指令。将一个任意寻址的存储器操作数的有效地址送给一个16位目标寄存器中,指令的源操作数必须是存储器操作数的地址,目的操作数必须是16位寄存器操作数。该指令常用来设置一个16位寄存器作为地址指针。
LDS:全地址指针传送指令。传送一个32位全地址指针到两个16位目标寄存器,地址指针包括一个段地址和一个偏移地址。首先从32位的双字存储单元取得低位字,作为全地址指针的偏移地址复制到一个指定的寄存器中(目的操作数中),再将高位字作为全地址指针的段地址复制到DS中。
LES:全地址指针传送指令。与LDS指令功能类似,只是把DS换ES。操作时首先从32位的双字存储单元取低位字,作为全地址指针的偏移地址复制到一个指定的寄存器中(目的操作数中),再将高位字作为全地址指针的段地址复制到ES寄存器。
LEA与LDS、LES允许的操作数类型相同,主要区别在于:LEA指令的目的操作数是16位偏移地址,而LDS、LES指令的目的操作数是32位的全地址指针。
标志寄存器传送指令:LAHF、SAHF、PUSHF、POPF。 LAHF(Load AH From Flags):读取标志指令。指令格式:SAHF,该指令的执行不影响标志位。
将寄存器中的低8位传送到AH中,包括5个状态标志SF、ZF、AF、PF、CF,其对应的位是第7、6、4、2、0,而第5、3、1位没有定义。
SAHF(Store AH into Flags):设置标志指令。指令格式:SAHF,该指令执行时,标志位被新的值所替代。 LAHF与SAHF刚好相反,执行时将AH寄存器的相应位送到标志寄存器的低8位,完成对5个状态标志位SF、ZF、AF、PF、CF的设置。
PUSHF(PUSH Flags):标志入栈指令。指令格式:PUSHF。 POPF(POP Flags):标志出栈指令。
PUSHF与POPF指令分别起保护标志和恢复标志的作用。
算术运算类指令:无符号数与有符号数采用同一套加减法指令的条件:1、要求参与加减法运算的加数、被减数或减数必须同为无符号数或有符号数;2、要用不同的状态标志位检测无符号数或有符号数的运算结果是否溢出(CF/OF)。
除INC/DEC指令不影响进位标志CF外,其他算术运算指令对OF、SF、ZF、AF、PF、CF均会产生影响。
加法:ADD、ADC、INC。
ADD:不带进位加。格式:ADD dst,src;注意: dst不能为立即数,dst,src不能同为存储器操作数。
ADC:带进位加。格式:ADC dst,src;注意:dst=dst+src+CF。 ADC主要用于多字节运算。 Exp:两个32位操作数1234A9A9H和5678C8C8H依次存在1000H开始的单元,低位在前高位在后,要求编程求和,结果仍然存在1000H开始的连续单元。 1000H A9; MOV SI,1000H 1001H A9; MOV DI,1004H 1002H 34; MOV AX,[SI] 1003H 12; ADD AX,[DI] 1004H C8; MOV [SI],AX 1005H C8; MOV AX,[SI+2] 1006H 78; ADC AX,[DI+2] 1007H 56; MOV [SI+2],AX MOV WORD PTR [SI+4],0 ADC WORD PTR [SI+4],0
减法:SUB、SBB、DEC、NEG、CMP。
DEC:减量指令。注意:段寄存器不能使用该指令。
NEG:取补指令。格式:NEG dst,该指令执行的结果总是使CF=1,除非操作数为0才使CF=0。
注意:当操作数dst=0时,结果不变;当操作数为-128(补码为80H)或-32768(补码为8000H)时,结果数值不变,但使OF置1。
乘法指令:MUL、IMUL。
特点:在指令中总有一个操作数隐含在AL或AX中。指令中的操作数字节,则另一个操作数隐含在AL中,乘积在AX中;指令中的操作数为字,则另一个操作数隐含在AX中,乘积在DX、AX中,其中DX作为存放乘积的高位扩展。
MUL:只对CF、OF有定义。乘积的高半部分不为0,则CF=OF=1;否则CF=OF=0。CF=OF=1表示结果的高半部分包含乘积的有效位,代表乘积的长度扩展;CF=OF=0代表乘积的长度没有扩展。 源操作数不能为立即数。
IMUL:格式与功能上与MUL类似,不同的是,MUL要求两乘数都为带符号数(补码),且乘积也是补码表示的数。
除法指令:DIV、IDIV、CBW、CWD。
特点:无符号数的除法DIV与带符号数的除法IDIV,被除数隐含在累加器AX(字节除)或DX和AX(字除)中。在除法运算中,如果除数是8位的,则要求被除数是16位的;除数是16位的,则要求被除数是32位的。 除法指令对所有状态标志均无定义。
DIV:对于字节除法,所得商存于AL,余数存于AH;对于字除法,商存于AX,余数存于DX。若除数为0,则在内部产生一个类型0的中断。
IDIV:与DIV指令相同,只是操作数是带符号数的补码,商和余数也是补码。其中,商可能为正或负,余数总是与被除数的符号相同,为正或负。除法指令的寻址方式与乘法指令相同,其目的操作数必须存放在AX中,或DX与AX中。注意:源操作数不能为立即数。 CBW(Convert Byte to Word):字节扩展指令。对标志位无影响,功能:把AL中的符号扩展到AH中。AL<80H,则扩展后(AH)=00H;否则扩展后(AH)=0FFH。
CWD(Convert Word to Double Word):字扩展指令。对标志位无影响,功能:将AX中的符号扩展到DX中。AX<8000H,则扩展后(DX)=0000H;否则扩展后(DX)=FFFFH。
BCD码调整指令:AAA、DAA、AAS、DAS、AAM、AAD。 AAA:加法的非压缩BCD码调整指令(ASCII码调整)。仅影响CF和AF。 DAA:加法的压缩BCD码调整指令(十进制加法调整)。仅OF无定义。 AAS:减法的非压缩BCD码调整指令。仅影响CF和AF。 DAS:减法的压缩BCD码调整指令。仅OF无定义。
AAM:乘法的非压缩BCD码调整指令。仅影响PF、SF、ZF。 AAD:除法的非压缩型BCD码调整指令。仅影响PF、SF、ZF。 逻辑运算与移位指令
需要对字节或字数据的各个二进制位进行操作时,可采用二进制位操作类指令。 逻辑运算类指令:AND、OR、NOT、XOR、TEST。
AND:逻辑与。格式:AND dst,src。两个操作数的对应位进行运算,与运算的结果送回到目的操作数。常用于对指定位进行清零。
OR:逻辑或。格式:OR dst,src。两个操作数按位进行或运算,结果送回目的操作数。
常用于对指定位进行置1操作。 XOR:逻辑异或。XOR dst,src。两个操作数按位进行异或运算,结果送回目的操作数。
注意:上述几种运算的目的操作数不能为立即数,两个操作数不能同时为存储器数。
TEST:测试指令。格式:TEST dst,src。将dst指定的内容按位做逻辑与运算,但不送回操作结果,只根据结果影响标志位。TEST指令的操作数寻址与AND指令相同。
常用来检测操作数的某些位是1还是0。
注意:上述指令对标志位的影响:标志位CF、OF复位,SF、PF和ZF由操作结果确定,AF未定义。
NOT:逻辑非。格式:NOT dst。指定的寄存器或存储单元的内容按位取反。常用来对某个数做求反运算。
非循环移位指令:SHL、SHR、SAL、SAR。 SHL:逻辑左移指令。指令格式:SHL dst,CL;CL是移位的位数。功能:将操作数左移,CL指定移位位数,最高位移入进位标志CF,移动后空出的最低位补0。
注意:操作数dst可以位寄存器数或存储器数。
当只移1位时,若符号位SF发生变化,则OF=1;否则OF=0。 Exp:MOV BL,01110101 MOV CL,4 SHL BL,CL 运算结果:(BL)=01010000,SF=0,CF=1,OF=1,ZF=0。
SHR:逻辑右移指令。指令格式与SHL类相同。功能:将操作数右移,CL指定移位位数,最高位补0,最低位移入CF。SHR指令的操作数寻址方式也与SHL相同。
当只移1位时,若移位后的符号位SF发生变化,则OF=1;否则OF=0。 以上两种操作:标志位SF、ZF、PF根据移位结果置位。
SAL:算数左移指令。与SHL指令功能相同,最高位移入标志位CF,但SAL将操作数视为带符号数。移动后空出的低位补0。
SAR:算术右移指令。与SHR指令功能相同,最低位移入标志位CF,但符号位保持不变。