汇编语言(1)8086指令系统常用指令总结
快速查阅方法:CTRL+F搜索
快速查阅方法:CTRL+F搜索
快速查阅方法:CTRL+F搜索
一、操作数的寻址方式
选择寻址方式有两条原则:第一实用,第二有效。
1.立即寻址
- 立即数可以理解为常数,且字长是不确定的,(例如02H,可以为0002H当被输入AX中时)在指令中只能作为源操作数。
- 立即寻址的指令一般用来给寄存器或者存储器赋初值。
;MOV 目的操作数,源操作数
MOV AH,80H ;把80H送入AH中
2.寄存器寻址
- 参加操作的操作数在CPU的通用寄存器中。
- SS、DS、ES既可做源操作数,也可做目的操作数,做目的操作数时源操作数不能是立即数,CS只能作为源操作数。
- 存放操作数的寄存器可以是16位通用寄存器 AX、BX、CX、DX、SP、BP、DI、SI;8位寄存器AH、BH、CH、DH、AL、BL、CL、DL;16位段寄存器CS、DS、ES、SS
- 有效地址EA=基址量(基址寄存器BX或BP提供的内容)+变址量(变址寄存器SI或者DI提供的内容)+位移量(8bit或16bit)
MOV AX,BX
3.直接寻址
- 有效地址EA = 位移量
- 指令中直接给出操作数的偏移地址
- 操作数默认为数据段,但可重设
- 寄存器主要是通用寄存器,且寄存器操作数的字长本身不确定,其字长取决于指令中另一个寄存器操作数,或通过其他方式指定字长
MOV AX,[2000H] ;表示该指令表示从数据段的 2000H 单元读出一个字送入 AX。
MOV ES:[2000H] ;该指令表示从附加段的 2000H 单元读出一个字送入 AX。
4.寄存器间接寻址
- 有效地址EA = (BX/BP)或(SI/DI)取出一个及地址或变地址因子。
- 操作数存放在内存中,数据在内存中的偏移地址为方括号中通用寄存器的内容。
- 8088指令系统中只有BX、SI、DI、BP允许使用间接寻址,使用BP时,默认的段地址在SS(堆栈段)中,而其他的默认在DS中。但都可以重设(不能重设位代码段)
MOV BX,1200H;把1200H送给BX
MOV AX,[BX] ; 把BX中存放的地址中存放的数据送给AX
代码中BX存入1200H的地址,然后送数据时,因为1200H存放的是8位的数据,所以把1200H的值赋给AL,1201H的值赋给AH。
5.寄存器相对寻址
- 有效地址EA = (BX/BP)或(SI/DI)取出一个及地址或变地址因子+DISP8/16。
- 操作数的偏移地址为寄存器的内容加上一个位移量。
- 相对寻址主要用于一维数组的操作。
- 常将位移量作为“表头”地址,间址寄存器的值作为表内相对地址。
MOV AX 1200H
MOV DS AX
MOV BX 2000H
MOV AL [BX]5 ;这一行等效为 MOV AL [BX+5] 表示把BX+5地址的数据送给AL
6.基址加变址寻址
- 有效地址EA = 基址寄存器内容+变址寄存器内容
- 操作数的段地址由选择的基址寄存器决定,基址寄存器为BX则段地址默认DS,基址寄存器为BP则默认CS。
- 相对寻址主要用于一维数组的操作。
MOV SI 1100H
MOV BX,SI
MOV AX,[SI+BX] ; 把2200H的数据给AL,2201H的数据给AH。
7.相对的基址加变址寻址
- 有效地址EA = 基址寄存器内容+变址寄存器内容+位移量.
- 操作数的段地址由选择的基址寄存器决定。
- 基址变址相对寻址方式主要用于二维表格操作。
MOV DI 1100H
MOV BP,DI
MOV AL,[BP+DI+5];或者写为[BP][DI]5 把2205H的数据给AL
8.隐含寻址
MUL BL ; 执行了AL * BL ->AX的操作
二、数据传送指令
除标志传送指令外,其它指令的执行对标志位不产生影响
1.通用数据传送类指令
- 该类所有指令的执行均不影响标志位
传送指令MOV
- 两操作数字长必须相同;
- 两操作数不允许同时为存储器操作数;
- 两操作数不允许同时为段寄存器;
- 在源操作数是立即数时,目标操作数不能是段寄存器;
- IP和CS不作为目标操作数,FLAGS一般也不作为操作数在指令中出现。
MOV DEST SRC ; DEST <- SRC
MOV [BX][BP],BX ; 这个例子是错的,因为BX BP是俩个基地址寄存器,从寻址方式的角度说是错的。
交换指令XCHG
- 俩操作数不能都是存储器操作数。两操作数类型必须一致。
- 不允许用段寄存器。
XCHG DEST,SRC ;把DEST操作数与SRC操作数的内容相互交换
堆栈操作指令 PUSH和POP
- 先进后出,以字节为单位
- 对于PUSH,操作数只能是寄存器(IP除外)或储存单元的16位字操作数据
- 对于POP,操作数只能是寄存器(IP和CS除外)或储存单元的16位字操作数据
PUSH SRC ; SP<-SP-2,[SP] <-SRC,就是把栈顶指针上移俩个字节,然后把源操作数压入堆栈。
POP DEST ; [SP] ->DEST,SP<-SP+2,把栈顶内容弹到目的操作数中,然后堆栈的栈顶指针下移俩个字节。
查表指令XLAT
- 该指令用来查表,表首地址在BX中,表长度可达256字节。
- 有俩个隐含操作数BX和AL。
- 用BX的内容代表表格首地址,AL内容为表内位移量。
XLAT ; AL<-DS:[BX+AL].BX的内容作为数据段中数据表的首地址,AL内容为查表的项数,将其对应的字节单元的值再送给AL。
字位扩展指令CWD与CBW
- 将符号数的符号位扩展到高位;
- 指令为零操作数指令,采用隐含寻址,隐含的操作数为AX及AX,DX
- 只用于有符号数,(无符号数的扩展规则为在高位补0)。
- CBW把AL内容扩充到AX,是字节到字扩展指令
- CWD把AX内容扩展到AX,DX,是字到双字扩展指令
CBW;若最高位为0,则AH=00H,若最高位为1,则DX=FFFFH。
CWD;若最高位为0,则DX=0000H,若最高位为1,则DX=FFFFH。
2.地址传送类指令
取有效地址指令LEA(取近地址指针)
- 将变量(属于存储器操作数)的16位偏移地址写入到目标寄存器。
- 当程序中用符号表示内存偏移地址时,须使用该指令。
- 源操作数必须是一个存储器操作数,目标操作数通常是间址寄存器。
LEA REG,MEM; 把源操作数的有效地址送到指定的寄存器。
LDS、LES指令
- LDS和LES均用于将一个32位的远地址指针写入到目标寄存器。
- LDS 通用寄存器,存储器操作数
- LES 通用寄存器,存储器操作数
LDS REG,MEM
LES REG,MEM
3.标志传送类指令
隐含操作数AH:
LAHF 标志寄存器低8位送AH
SAHF AH送标志寄存器低8位
隐含操作数FLAG
POPF 将标志寄存器的内容压栈
PUSHF 将栈顶内容送标志寄存器
注:SAHF和POPF指令将直接影响标志位,而其他传送均不会对标志位产生影响。
3.输入输出指令
专门面向IO口操作的指令
指令寻址方式:根据端口地址码的长度,指令具有两种不同的端口地址表
现形式。
直接寻址:端口地址为8位时,指令中直接给出8位端口地址;寻址256个端口。
间接寻址:端口地址为16位时,指令中的端口地址必须由DX指定;
可寻址64K个端口。
IN acc PORT ;
OUT PORT acc ;
三.算术运算指令
算术运算指令的执行大多对状态标志位会产生影响
如果是存储器操作数,需要声明操作数的字长(用PTR运算符)
加法指令ADD ADC INC
- ADC指令多用于多字节数相加,使用前要先将CF清零
- ADD指令的执行对全部6个状态标志位都产生影响,ADC指令的要求和影响与ADD相同
- 对操作数的要求与MOV指令相同
- INC指令只影响5个标记位,不影响CF标记位
ADD OPRD1,OPRD2; OPRD1+OPRD2---->OPRD1
ADD OPRD1,OPRD2, OPRD1+OPRD2 + CF --->OPRD1
INC OPRD ;OPRD + 1 OPRD不能是段寄存器,不能是立即数
减法指令 SUB SBB DEC CMP NEG
- SUB指令对标记位的影响与ADD相同
- NEG对一个负数取补码就相当于用零减去此数,为零才会使CF为0;执行NEG指令后,一般情况下都会使CF为1,除非给定的操作数;用0减去操作数,可以得到负数的绝对值
- 当指定的操作数的值为80H(-128)或为8000H(-32768),则执行NEG指令后,结果不变,但OF置1,其它情况下OF均置0
- CMP的执行结果不影响操作数,只影响标记位
- DEC指令只影响5个标记位,不影响CF标记位
SUB PORD1 PORD2 ;PORD1 - PORD2 -->PORD1
SBB PORD1 PORD2 ;PORD1 - PORD2 - CF --->PORD1
DEC PORD1 ; PORD1 - 1 ; 指令对操作数的要求及对标志位的影响与INC相同
NEG PORD ; 0 - PORD
CMP PORD1 PORD2 ; PORD1 - PORD2
CMP详解
乘除指令
乘除运算均采用隐式操作数
乘法命令
- 乘法指令采用隐含寻址,隐含了存放被乘数的累加器AL或AX,以及存放结果的AX或AX,DX;
- 有符号乘法执行原理:先把俩个操作数取补码,然后运算,然后再取补码
; 无符号乘法,PORD不能是立即数 若PORD是字节数AL * PORD - > AX
;若PORD是16位数AX * PORD -> DXAX
MUL PORD
MUL BYTE PRT[BX]
;有符号乘法
;指令格式及对操作数的要求与MUL指令相同。
IMIUL PORD
除法命令
- 要求被除数是除数的双倍字长
- 若PORD是字节数,则AX/PORD,AH = 余数,AL = 商
- 若PORD是双字节数,则DXAX/PORD,AX = 商,DX = 余数
DIV PORD
IDIV PORD
四.逻辑运算指令
概述:
- 对操作数的要求大都与MOV相同(除了非运算)
- “非”运算指令要求操作数不能是立即数;
- 除“非”运算指令,其余指令都会影响除了AF外的五个状态标志
- 无论执行结果任何,都会使标志位OF = CF=0
与指令AND:
- 与指令使某些位不变,某些位清0.
- 在操作数不变的情况下使CF和OF清零
或指令OR
- 使某些位不变,某些位置“1”
- 无论执行结果任何,都会使标志位OF = CF=0
非指令NOT
- 取非后再送回源地址
- 指令的执行对标记位没有影响
异或指令XOR
- 进行数据自身的清零:XOR AX AX ; 清零AX
测试指令TEST
- 不返回目的操作数,结果反映在标记位上
- 用来测试某些位的状态
AND PORD1 PORD2
OR PORD1 PORD2
NOT PORD
XOR PORD1 PORD2
TEST PORD1 PORD2
移位操作指令
概述:
- 指令格式在形式上为双操作数,本质上为单操作数;
- 目标操作数为移动对象(当目标为存储器对象时,还要说明字长),源操作数为移动次数
- 移动1位由指令直接给出,多位则由CL指定
非循环移位指令
指令执行后影响CF PF ZF SF OF位
;算数移位指令
SAL/SAR DEST,CNT; 用于有符号数据的移位,左移1相当于乘2,右移1相当于除以2
;逻辑移位指令
SHL/SHR DEST,CNT;用于无符号数据的移位,左移1相当于乘2,右移1相当于除以2
循环移位指令
把CF作为目的操作数的扩展位
指令执行后影响CF PF ZF SF OF位
ROL DEST,CNT ;左循环移位
ROR DEST,CNT ;右循环移位
RCL DEST,CNT ;带进位左循环移位
RCR DEST,CNT ;带进位右循环移位
五.串操作指令
概述:
串指令的执行要确定串的首地址,串区域,串长度,串方向
- 源串一般存放在数据段,偏移地址由SI指定。允许段重设
- 目标串必须在附加段,偏移地址由DI指定。
- 串长度由CX决定
- 穿的操作方向由DF决定,为1则增地址方向,为0则反之。
重复前缀
REP MOVS/LODS/STOS; 无条件重复前缀当CX不为0时,则重复指令,常用于传送类指令前
REPE MOVS/LODS/STOS; 有条件重复类指令当CX不为0且CF=1,则重复执行
REPNE/REPNZ;;不相等重复前缀;若CX=0或ZF=1则推出重复炒作循环,若CX不为0且ZF=0则执行指定串操作一次
串传送指令MOVS
- 指令的执行结果不影响标记位
例子 :
LEA SI,MEM1
LEA DI,MEM2
MOV CX,200
CLD
REP MOVSB
HLT
串比较指令
- 指令的执行结果不影响标记位
例子:判断俩个字符串是否相等
LEA SI,MEM1
LEA SI,MEM2
MOV CX,200
CLD
REPE CMPSB
JZ STOP; 判断zf=1,如果等于1,说明是cx=0,则串相同
DEC SI; 指向存放不相等数据的位置
MOV AL,[SI]
MOV BX,SI
STOP:HLT
串扫描指令SCAS
常用于再指定存储区域中寻找某个关键字;与CMPS的操作相似,但是源操作数变为了AX或者AL,指令用DI指向的串操作元素与AL/AX寄存器的内容比较。
串装入指令LODS
- 对字节,则把[DS:SI]–>AL;对字,则[DS:SI]->AX
- 用于将内存某个区域的数据串依次装入累加器,以便显示或输出到接口。
串存储指令STOS
- 对字节,则把AL–>[ES:SI];对字,则AX–>[ES:SI]
六.程序控制类指令
只改变了IP的值而改变了指令的执行顺序,叫段内转移;若同时改变CS与IP的值而改变了指令的执行顺序,则为段间转移。
1.无条件转移
JMP OPRD
段内转移
JMP DISP8; IP=IP+8 段内短程转移,目标地址与JMP指令处所在地址的距离再-128到127内
JMP DISP16;IP = IP+16 段内进程直接转移,目标地址与JMP指令处所在地址的距离再-32768到32767内
JMP REG/MEM IP的内容由寄存器或存储单元提供,目标地址与JMP指令处所在地址的距离再-32768到32767内
段间转移
- 间接转移:转移的目标地址由指令的32位操作数给出,32位目标地址须放在内存中
- 直接转移:指令中直接给出32位目标地址,包括段地址和偏移地址
JMP ADDR ; 段间直接转移
JMP MEM ; 段间间接转移
JMP DWORD PTR[BX]
2.条件转移指令
- 有19条件转移指令,根据标志寄存器中各标志位的状态;
- 目标地址必须再现行的代码段CS内,且以当前指针寄存器IP内容位基准,位移再-128到+127内
3.循环控制指令
CX或标志为ZF进行测试,确定是否循环
指令格式 | 执行操作 |
---|---|
LOOP OPRD | CX= CX-1;若CX不为0,则循环 |
LOOPNZ/LOOPNE OPRD | CX=CX-1,若CX不为0且ZF=0,则循环 |
LOOPZ/LOOPE OPRD | CX = CX-1,若CX不为0且ZF=1,则循环 |
4.过程调用和返回指令
有点像函数
段内调用指令中直接给出子过程的入口地址,段间调用则由内存获得子程序的入口地址
CALL NEAR PTR OPRD;
CALL FAR PTR OPRD ;
;例子
;段内调用
CALL TIMER ; 直接调用
CALL WORD PTR[SI] ;间接调用
;段间调用
CALL FAR TIMERE;直接调用
CALL DWORD PTR[SI];间接调用
5.中断指令和处理器控制指令
INT n 中断指令
IRET 中断返回指令
NOP指令 不操作,调试程序时用它占用一定的存储单元以便再正式运行时用其他指令取代
HLT 停机指令 使CPU处于暂停状态
WAIT 等待指令
LOCK 总线封锁指令
ESC 交权指令