最近学习这东西的时候深感不便,于是花了些时间来整理了一下,同时加深一下之前的记忆,前部分是图,后部分是文字叙述。
注:这对其中一小部分指令的介绍还是有那么一奈奈的不详细的,想要深入了解尽量还是去看专业介绍,该图的主要功能就是让人麻溜的想起来。
思维导图

8086汇编指令集
一.数据传送类
通用类
MOV
格式:MOV dest,src;它可以传送字节操作数(8位),也可以传送字操作数(16位)。
注意:1.它不能直接实现存储单元间的传送
2.它不能直接实现立即数到段寄存器间的传送
3.它不能实现段寄存器之间的传送
PUSH
格式:PUSH src;它只能传送字操作数
它是实现将寄存器或者存储器的内容压入栈,压入前 ,堆栈指针寄存器sp=sp-2,然后高8位放在sp+1,低8位放在sp位置中
POP
格式:POP dest;也是只能传送字操作数
它实现了将寄存器或存储器的内容出栈,出栈时,首先弹出sp所指向的内容到外部,再弹出sp+1的内容到外部,然后sp=sp+2;
XCHG
格式:XCHG dest,arc; 它的作用是将目标操作数与源操作数互换,但不能都是存储器
XLAT
字节的查表转换指令
输入输出类
IN
格式:IN AX/AL 端口,用于从端口接收数据到累加器acc,端口地址可以存放在DX中
OUT
格式:OUT 端口 AX/AL,用于从累加器向端口发送数据,端口地址可以存放在DX中
目标地址传送指令
LEA
格式:LEA reg16 ,mem16;将一个16位偏移地址传送到一个16位目标寄存器
LDS
格式:LDS reg16 , mem32;传送一个32位的远地址指针,包括16位偏移地址和16位段地址,前者送到指定寄存器rwg16,后者送到数据段寄存器DS
LES
与LDS类似,偏移送进指定寄存器,段送进ES
标志传送指令
LAHF
将标志寄存器的五个标志位传送到累加器AH的对应位
SAHF
将AH的数据传送到标志寄存器
PUSHF
将标志寄存器中内容压入栈
POPF
将栈中内容弹出到标志寄存器
二.算术运算指令
加法
ADD
格式:ADD dest,src;将源操作数与目标操作数相加,结果放在目标操作数上。两者不能同时是存储器,有符号数相加溢出,OF设为1,无符号数相加溢出,即最高位产生进位,CF设为1
ADC
带进位加法指令,格式同上,将目标操作数与源操作数相加,再加上进位标志CF的内容,然后把结果返回目标操作数。
主要用于多字节相加,低位字节进位,高位字节相加时把该进位加进去。
INC
格式: INC dest;将目标操作数加1
AAA
加法的ASCLL码调整指令
DAA
加法的十进制调整指令
减法
SUB
格式:SUB dest ,src;dest等于dest减去src,不允许两个存储器相减,这个借位和溢出同ADD。另外,当一个带符号的较小数减一个带符号的较大数产生负结果时,SF置为1。
SBB
格式同上,带进位减法指令,dest等于dest减去src再减去CF,主要用于多字节
DEC
格式同INC,将目标操作数减1
NEG
格式:NEG dest;它是求补指令,dest等于0减去dest
CMP
格式:CMP dest ,src;比较指令,是将dest减去src,但不给谁把结果会赋过去,比较的结果反映在标志位上,两个操作数值不变。
ZF是零标志位,当结果为0时,ZF为1,否则为0。在CMP就是src和dest相等时,ZF为1。
AAS
减法的ASCLL码调整指令
DAS
减法的十进制调整指令
乘法
MUL
格式:MUL src;默认另一个乘数在AL(8位),AX(16位)中。src则在存储器或寄存器里
字节操作:两个字节相乘,结果可能为16位,存放在AX中。
字操作:两个字相乘,结果可能为32位,高16位存放在DX中,低16位存放在AX中。
如果运算结果的高半部分为0(AH为0或DX为0),则CF和OF为0。
IMUL
格式同上MUL,它是进行带符号数的乘法,其他与MUL一样
AAM
乘法的ASCLL码调整指令
除法
DIV
格式:DIV src;默认被除数是在AX(字节除法),DX:AX(字除法),src必须是寄存器或者存储器操作数
无符号数字节除法:AL等于AX/src,AH等于AX%src。
无符号字除法:AX等于(DX:AX)/src,DX等于(DX:AX)%src
IDIV
格式同上DIV,这是带符号数的除法
AAD
除法的ASCLL码调整指令
转换指令
前言:在算术运算指令中,通常对操作数的字长有一定要求,如在加法减法乘法中,要求两个操作数的字长是必须相等的,在除法中,被除数需要是除数的双倍字长,故,有时需要将一个8位数扩展为16位,或者16位扩展为32位。
CBW
顾名思义,byte to word,它将字节转换成字,8位变16位,同时隐含了对寄存器AL,AH的操作。
如果AH小于80H,AH为0。AL大于等于80H,AH为FFH
CWD
word to double word,将字转换为双字,16位变32位,它隐含的寄存器则是AX和DX。
如果AX小于8000H,DX等于0。如果AX大于等于8000H,DX等于FFFFH
三.逻辑运算和移位指令
逻辑运算指令
AND
格式:AND dest,src; dest等于dest & src,即两数全为1才为1,目标和源操作数不能同时是存储器。,两操作数的位数必须相等,对每一位进行逻辑运算
TEST
运算与AND相同,不过结果不会返回dest,而是表现在标志寄存器的标志位上
OR
格式:OR dest,src ; dest等于dest"或运算" src,即两数全为0才为0,并将结果返回dest,常见作用是将特定位与1或运算把结果设为1。
小记:AND和OR有一个共同特性,如果一个寄存器的内容与该寄存器本身进行AND或OR运算,寄存器的内容不会变,但SF,ZF,PF标志位会根据结果改变,且CF,OF会清零。
XOR
格式同AND,返回同AND,它进行的是异或运算,即两数相同为0,不同为1,常见作用是将寄存器清零:XOR AX AX
NOT
格式:NOT dest;将各个位求反,返回到dest中,也就是0变1,1变0。
移位指令
SHL/SAL
格式:SHL/SAL dest ,1/CL;逻辑左移/算术左移指令,作用是将dest左移1位或者CL中指定位数,操作数的第1位/CL位移进CF中,最低位补零。两条指令运算结果是相同的。
SHR
逻辑右移指令,格式同上,右移时,第1位/CL位移进CF中,高位补零。
SAR
算术右移指令,格式同上,它与SAR有着些许差异,虽也是将第1位/CL位移进CF中,但最高位不变。
举个栗子:MOV AL ,80H(1000 0000B);
SAR AL ,1;
则 AL =C0H(1100 0000B)。
小记:根据规定,当移动的位数不为1时,移动的数必须存放在CL中
循环移位指令
ROL
格式:ROL dest 1/CL,将目标操作数向左循环移动一位或CL内指定位数,第1位/CL位移进CF。
再举个栗子:mov al, 00101111b
rol al, 3b ;
循环左移3位, 将(从左往右)第三位移入CF位,CF位置为1, 低5位左移三位,并且将高三位001移入低三位,al结果是01111 001
ROR
格式同上,作用也同上,把高换成低,左移变成右移
RCL
格式仍同上,不过处理不同,它是将目标操作数连同标志位CF一起移动,此时CF当脑袋,RCL操作后,CF位被操作数的第1位/第CL位占领,而原本CF的值因为循环跑到了操作数的屁股后面
再再举个栗子:mov al, 01110100b
rcl al, 2 ;
这是将 01110100左移2位, rcl al, 2相当于rcl al, 1执行两次。第一次执行前, CF=0,执行之后的结果是CF=0, al的值是11101000。第二次执行前, CF=0, 而执行之后的结果是CF=1,AL的值是 11010000
RCR
同上同上同RCL,屁股跟脑袋换换就行
四.串操作指令
前谈:
先了解一些东西吧,字符串操作中:
1. DS:SI通常指向源操作数的物理地址,ES:DI通常指向目标操作数的物理地址
2. DF方向标志决定了修改地址指针是增量还是减量,DF 为0时,地址指针增量,也就是从低地址向高地址,DF为1时,地址指针减量,即从高到低。
3. 有的串操作可以加重复前缀REP ,则该操作就重复进行,循环的次数由CX中的数来决定。 在进行有REP前缀串操作时,会先检查CX,若CX为0,则直接退出操作,不为0,则执行串操作,然后根据DF标志修改地址指针,再然后CX减1,后面重复以上操作直至CX为0。
MOVS
字符串传送指令,它是分为:MOVSB传送字节单位,MOVSW传送字单位,传送也就是从源地址DS:SI到目标地址ES:DI,传送数量看CX,传送方向看DF
CMPS
字符串比较指令,格式比较MOVS而言反过来了:CMPS src (DS:SI),dest(ES:DI);它将两个字符串上的内容逐个进行比较,比较的结果会体现在标志位,若两个比较的字或字节相等,ZF为1,不相等则ZF为0。
单独说明一下前缀:
1. REPE(REPZ)表示当CX不等于0且ZF等于1时,才会继续比较,就是找到不一样的字符它就停了。
2. REPNE(REPNZ)表示当CX不等于0且ZF等于0时,才会继续比较,也就是找到一样的字符它才停
SCAS
字符串扫描指令,它在字符串中搜索特定的关键字,字符串的起始地址放在ES:DI中,关键字放在AL或AX中,将关键字与字符串中的元素逐个进行比较,结果反应在标志位上。
LODS
将一个字符串(DS:DI)中的字或字节逐个装入AL或AX中
STOS
将AL或AX的值送入到字符串(DS:DI)的某个位置中
五.控制转移指令
JMP
1. 段内直接转移,格式:JMP next(名字,乱起);JMP的操作数是一个近标号next,该标号在本段之内,执行JMP后,会自动计算JMP的下一条指令到有next标号指令的相对位移量disp,IP直接加disp,然后就跳到next了。
2. 段内间接转移, 格式:JMP reg16/mem16; reg16或mem16会直接取代IP的值。
3. 段间直接转移,格式:JMP far_next(名字,乱起);JMP的操作数是一个远标号far_next,该标号在段外面,执行JMP后,CS会被far_next标号的段地址取代,IP被标号的偏移地址取代,直接一个大迁徙。
4. 段间间接转移,格式:JMP mem32,前两个字节给IP,后两个字节给CS。
循环控制指令
LOOP
格式:LOOP next; 先将CX内容减1,若CX不等于0,则继续next,相当于在next处循环了CX次
过程调用指令
CALL
1. 段内直接调用,格式:CALL next,会计算CALL的下一条指令到next标号指令的16位相对偏移量disp,然后将IP内容压入栈内,IP再加上disp。
2. 段内间接调用,CALL reg16/mem16,先将IP内容压入栈内,然后将reg16或mem16送到IP。
3. 段间直接调用,格式:CALL far_next; CALL的操作数是一个远标号far_next,该标号在段外面,执行CALL后,CS会被far_next标号的段地址取代,IP里的值先压入栈,然后再用标号的偏移地址取代IP。
4. 段间间接转移,格式:CALL mem32,IP先压入栈,然后前两个字节给IP,后两个字节给CS。
RET
返回指令,格式:RET (num可写可不写)
1.近地址:将堆栈中的一个字弹回到IP,SP自加2,如果带num的话,SP还会加上num,也就是舍弃了堆栈中的num字节
1.远地址:先将堆栈中的一个字弹回到IP,SP自加2,再将堆栈的一个字弹回到CS,SP再加2,带num的话仍同上,SP会再加上num,舍弃堆栈中的num个字节
中断指令
INT
格式:INT n; n是0-255的一个数,执行指令时,先将标志寄存器推入栈,然后清除IF和TF,再将CS推入栈,然后n乘4得到中断矢量的地址,矢量的第二个字送入CS寄存器,然后将IP推入栈,矢量的第一个字送入IP
INTO
溢出中断指令,执行时会检测OF,如果OF为1,则启动类似INT的中断过程
IRET
中断返回指令,它将先将堆栈中的一个字弹回到IP,SP自加2,再将堆栈的一个字弹回到CS,SP再加2,然后再再将堆栈中一个字弹回标志寄存器,SP再再加2,就是INT反过来的东西
六.处理器控制指令
标志位操作指令
CLC
Clear Carry Flag ,CF置为0
STC
Set Carry Flag,CF置为1
CMC
对CF求反
CLD
DF置为0
STD
DF置为1
CLI
IF置为0
STI
IF置为1
其他控制指令
NOP
这玩意是空操作指令,也没啥操作数,执行时啥也不干,单纯占占时间
HLT
执行后,CPU会进入暂停状态,外部中断或者RESET可以让CPU退出暂停
WAIT
如果8086CPU的TEST----引脚信号无效(高电平),则该指令可以让CPU进入等待状态
LOCK
刻可以放在任何指令前,会迫使CPU锁定信号线LOCK----维持低电平,直到执行完此指令
ESC
格式:ESC op,src;它会让其他处理器使用8086寻址方式,并从8086CPU的指令队列取得指令