三A寻址和指令摘要.docx
《三A寻址和指令摘要.docx》由会员分享,可在线阅读,更多相关《三A寻址和指令摘要.docx(18页珍藏版)》请在冰豆网上搜索。

三A寻址和指令摘要
3.8086/8088寻址和指令摘要
8086/8088CPU的指令系统由94条指令构成。
指令中的操作数可以用7种方式表达(7种寻址方式);跳转指令的跳转地址可以用4种方式表达。
3.180x86的指令概况
1.指令格式
指令格式:
[标号:
]操作码操作数[;注释]
操作数个数:
●无操作数指令──比如CPU暂停指令不是针对某个具体数据的操作,就无操作数
还有的指令操作对象固定,称为默认操作数,操作数无需写出
●一操作数指令──指令功能就是对一个数的处理,比如加1、减1
●二操作数指令──最典型的指令就是对两个数的操作,如算术运算、逻辑运算指令
●(286以后有三操作数指令)
2.机器指令长度
助记符指令经过汇编就变成了2进制(16进制)形式的机器指令。
8086的94条机器指令长度是不同的,最短的机器指令长度1个字节,最长的7个字节(32位处理器【386以后】的指令长度为1~14个字节)。
3.指令的执行时间
随着指令功能不同,执行不同指令所耗费的时间也不同。
了解这部分内容,可以计算出给定的一段程序总的执行时间是多少。
指令执行时间的单位──时钟节拍数=时钟周期数。
系统时钟──振荡电路产生稳定的周期脉冲,作为系统个芯片工作的统一节拍;
时钟周期──振荡电路频率的倒数,8086的最高允许振荡频率是4.7MHz,8026的最高允许振荡频率是16MHz,8036的最高允许振荡频率是40MHz,8046的允许振荡频率是66-100MHz,P4允许振荡频率是nGHz。
执行时间──基本执行时间+取指令时间+计算存储器地址+存取操作数时间
(2~184)(0)(5~12)(?
)
了解指令执行时间的区别,在设计实时性要求较高的程序时可以选择。
比如实现同样功能,哪个指令更简短。
MOVAX,0;3字节,时钟周期4
SUBAX,AX;2字节,时钟周期3
3.28086的寻址方式
对于数据处理一类的指令,其操作数就是以各种形式表达的数据。
(数据的表达方式=数据的寻址方式)
对于程序跳转一类的指令,其操作数是跳转目的地址。
(目的地址的表达=地址的寻址方式)
3.2.1数据的寻址方式
1.立即(数)寻址——操作数是8位、16位的常数,386以上处理器可以用32位常数。
例如:
MOVCX,2000H;2000H就是一个立即数
2.寄存器寻址——指令中使用寄存器名称,表示以寄存器的内容为操作数。
对于8位数据可以用AH、AL、BH、BL、CH、CL、DH、DL;
对于16位数据可以用AX、BX、CX、DX、SP、BP、SI、DI;
例如:
MOVAX,5;AX是寄存器,5是立即数
MOVCL,0FFH;CL是寄存器,0FFH是立即数
以下五种就是关于存储器地址的寻址方式,通常指令以某种方式提供偏移地址,与默认段地址自动合成。
偏移地址又称有效地址(EA),可以直接给出也可以间接给出,可以由一个数据决定也可以由2个或3个数据合并决定。
3.直接寻址
用方括号括起来的立即数(不超过16位2进制数),此时这个立即数由于用了括号就表示一个存储单元的偏移地址,默认与段地址DS搭配得到物理地址。
变量名具有地址属性,用于指令中表示数据,等于直接寻址。
(此时有无方括号等效)
例:
MOVCX,[2000H];将DS:
2000H单元内容赋值给CX
MOVBX,VAR1;将DS:
VAR1单元内容赋值给BX。
可写成“MOVBX,[VAR1]”
4.寄存器间址
用方括号括起来的寄存器,此时寄存器的内容不是操作数,而是偏移地址。
与段寄存器默认搭配规则:
DS+[BX]/[SI]/[DI];可以强行指定段寄存器,如“ES:
[BX]”
ES+[DI]只在串指令DI默认与ES搭配,其它指令DI与DS搭配
SS+[BP]
可见,只有这4个寄存器可以间址。
(只有这4个寄存器有资格用方括号!
)
5.寄存器相对寻址
偏移地址由两项内容共同构成,一个位移量和一个寄存器。
具体写法:
[寄存器+位移量]或位移量[寄存器]
例:
MOVAX,[BX+6];DS+(BX内容+6)构成被操作的数据的地址,
MOVAX,ES:
6[BX];指令中强行指定使用ES(否则默认DS)
最常用形式MOVAX,变量[寄存器];变量有地址属性(见直接寻址)
与段寄存器默认搭配:
DS+[BX]/[SI]/[DI]+常数(位移量);可以强行指定段寄存器
SS+[BP]+常数(位移量)
6.基址+变址
偏移地址由两个寄存器的内容合成,如:
MOVAX,[BX][SI]或MOVAX,[BX+SI]
默认搭配:
DS+[BX]+[SI]/[DI]
SS+[BP]+[SI]/[DI]
例:
MOVAX,[BX+SI]或MOVAX,[BX][SI];此时,BX指向表头,SI是偏移量
7.相对基址+变址
最复杂的地址组合,偏移地址由两个寄存器的内容外加偏移量三部分合并。
典型用法:
变量[BX][SI];用于访问二维数组,变量是数组名、BX选择行、SI选择列(元素)。
;变行修改BX,变列修改SI。
对于286以上的CPU寻址方式又增加了:
比例变址、比例基址+变址、比例相对基址+变址
寻址方式的概括(从操作数书写形式来说):
1)立即数无论数值如何变化,写法只有一种──常数;
2)寄存器数无论是哪个寄存器,写法只有一种──寄存器名;
3)存储器数是用存储单元地址来表达,存储单元地址可以用5种形式来表示。
存储单元的20位地址=物理地址=段地址(系统指定)+偏移地址(有效地址,EA);
有效地址由指令给出,其构成成分不外乎以下三种:
●位移量──8位或16位的一个有符号数据(或变量名),表示对地址的修正值;
●基址──存放在BX(特殊情况用BP)中的地址,通常是数组或字串的首地址;
●变址──存放于SI、DI中的地址,通常是基址的补充变化值。
将来构成有效地址可能是上述3因素的五种组合:
只有位移量——————直接寻址
只有基址或只有变址——寄存器寻址
位移量+基址————寄存器+数值
基址+变址————BX+(SI或DI)
位移量+基址+变址——2寄存器+数值
3.2.2程序转移的寻址方式(地址寻址=地址表达)
循环、分支、子程序调用的实质就是程序的执行不按顺序,而是发生地址“突变”——跳转。
实现跳转的方法就是CPU专门设计了一组修改程序指针(CS:
IP)的指令,我们从宏观效果称呼这类指令为跳转指令、循环指令、子程序调用、中断调用指令等。
1.段内直接寻址(CS不变)
跳转指令中直接以标号或常数的形式给出跳转字节数,IP=IP+跳转字节数。
注意IP是被修改,不是替换。
例:
JMP3或JMP-5
更实用的是JMP标号;标号前可标出SHORT或NEARPTR
CALL段内过程名;默认16位操作数,无需属性说明
如果是8位数据称为短跳转(SHORT),跳转范围-128~+127字节;
如果是16位数据称为近跳转(NEAR),跳转范围-32768~+32767字节。
条件跳转指令(17条)只能使用本寻址方式且限定8位短跳转。
2.段内间接寻址(CS不变)
指令中以除立即数以外的6种寻址方式给出一个寄存器内容或存储单元内容,以此内容取代IP值。
例:
JMPBX/[BX]/[3E00H]/[BX+2]/[BX][SI]/[BX+SI+3E00H]
3.段间直接寻址(CS也变)
指令给出一个外段的标号或过程名(理论上也可是常数的段地址和偏移地址),CS、IP均被替换,通常需要用FARPTR对操作数进行说明。
例:
JMPFARPTR标号;跳到另外一个段的标号处
CALL外段过程名;调用(跳转)另外一个段的子程序
4.段间间接寻址(CS也变)
指令中以访问存储器的5种寻址方式给出一个存储单元,从中取出2个字(4个连续字节),低地址的赋值给IP,高地址的字赋值给CS。
例:
JMPDWORDPTR[BX]/[3E00H]/[BX+2]/[BX][SI]/[BX+SI+3E00H]
中断调用属于此类,但其存储单元地址的获取方式比较特殊。
3.38086的指令总览
1.共94条指令,分为六类:
数据传送16条;算术运算18条;
逻辑运算13条;串处理指令8条;
控制和跳转25条(27条);处理机指令12条。
2.学习指令五方面
格式、功能、执行过程、对标志的影响、适用范围(字节/字,对操作数限制)
3.指令对操作数的限制:
常规、隐含(默认)、限定。
●一般指令的操作数非隐含也无特殊限定,只要按基本规则使用即可;
●有的指令操作数非隐含但是限定,如移位指令中必须CL、端口指令中必须AC等;
●隐含寻址:
有些指令中不写操作数,但其操作数是固定(默认)的。
比如串操作指令不用写操作数,但是默认:
源串由DS+SI确定,目的串由ES+DI确定;十进制调整指令(默认AL);换码指令(默认AL、BX)等。
乘除指令只需给出一个操作数,另一个操作数默认为AX。
4.指令中操作数使用基本规则
●目的操作数不能是立即数(与高级语言同样道理:
赋值和输入不能给常量);
●双操作数最多一个存储器数(P.40、P.58:
单操作数指令不许使用立即数);
●注意指令中的操作数类型(字节/字)要明确、要一致。
●操作数代号:
SRC(源)、DST(目的)、OPR(操作数)、CNT(计数值)、AC(表示AX或AL);
3.3.1数据传送16条共同特点:
不影响标志位
基本功能:
将源操作数(SRC)传送(赋值)给目的操作数(DST)
共同特点:
不影响标志位
1.通用传送——4条
MOVDST,SRC;数据传送,DST←SRC,字或字节,七种寻址组合
PUSHSRC;数据入栈,目的数隐含,不许立即数,只能字操作
;(SP)←(SP)-2,先修改指针
;((SP)+1,(SP))←(SRC),数据入栈
POPDST;数据出栈,源操作数隐含,不许CS,不许立即数
;(DST)←((SP)+1,(SP)),先取出数据
;(SP)←(SP)+2,再修改指针,DST不许立即数
XCHGOPR1,OPR2;寄存器与寄存器、寄存器与存储器交换数据
2.累加器专用传送——3条
INAC,端口地址;从端口输入数据,四种组合
OUT端口地址,AC;向端口输出数据,四种组合
XLAT[OPR];换码指令(查表指令),默认BX指向表头,AL为偏移量,
;操作:
AL←((BX)+(AL))
端口的寻址:
端口地址最大16位,限定使用DX间接寻址(而且可以不加括号)。
如果端口地址在255以内,可以直接寻址。
端口输入:
INAC,端口地址
具体格式4种:
INAL,直接寻址(8为以内的地址);长格式
INAX,直接寻址(8为以内的地址);长格式
INAL,DX;短格式
INAX,DX;短格式
端口输出:
OUT端口地址,AC
具体格式4种:
OUT直接寻址,AL;长格式
OUT直接寻址,AX;长格式
OUTDX,AL;短格式
OUTDX,AX;短格式
3.地址传送——3条
LEAREG,SRC;有效地址送REG寄存器,目的只能是寄存器,
;源必须是五种存储器数之一
LDSREG,SRC;存储器双字送REG寄存器和DS
LESREG,SRC;存储器双字送REG寄存器和ES
4.标志传送——4条
本组指令直接保存或修改标志寄存器,不是间接影响标志,与“传送指令不影响标志”的说法无冲突。
LAHF;标志寄存器低字节送AH(低字节含6个状态标志5个)
SAHF;AH内容送标志寄存器低字节
PUSHF;标志寄存器内容入栈(字操作)
POPF;栈顶内容弹出到标志寄存器
5.符号扩展——2条
CBW;字节扩展为字,8位数据AL符号扩展为16位的AX
CWD;字扩展为双字,16位数据AX符号扩展为32位的DX:
AX,
3.3.2算术运算18条共性:
影响标志
1.加法——3条
ADDDST,SRC;不带进位加
ADCDST,SRC;带进位加
INCOPR;加1指令,不影响CF标志
2.减法——5条
SUBDST,SRC;不带进位减
SBBDST,SRC;带进位减
DECOPR;减1指令,不影响CF标志
NEGOPR;求补指令(求补运算:
全部按位取反,末位加1)
CMPOPR1,OPR2;比较指令(减法操作但不存结果,为获标志)
3.乘法(目的操作数隐含为AC)——2条
MULSRC;无符号数相乘
IMULSRC;有符号数相乘
字节相乘(AL×SRC)结果在AX为16位,
字相乘(AX×SRC)得双字(DX)(AX),由源操作数的类型决定。
4.除法(目的操作数隐含为AC)——2条
DIVSRC;无符号数相除
IDIVSRC;有符号数相除
源操作数为除数,隐含的目的操作数为被除数;
源数为8位时,被除数默认AX,商在AL,余数在AH;
源数为16位时,被除数默认(DX)(AX),商在AX,余数在DX;
所以在除法指令之前,应将被除数放到默认寄存器,必要时做符号扩展(CBW、CWD)
5.十进制调整(单操作数指令,默认AL)——6条
DAA;压缩BCD码加法十进制调整
DAS;压缩BCD码减法十进制调整
AAA;非压缩BCD码加法十进制调整
AAS;非压缩BCD码减法十进制调整
AAM;非压缩BCD码乘法十进制调整
AAD;非压缩BCD码除法十进制调整
对BCD码进行一次运算之后必须跟一个调整指令,才能保证结果依然是BCD码。
3.3.3逻辑运算13条
1.逻辑运算——5条
ANDDST,SRC;逻辑与:
用于某些位清0(屏蔽),源数为0的位结果得0
ORDST,SRC;逻辑或:
用于某些位置1,源数为1的位结果得1
NOTOPR;逻辑非:
操作数按位取反(比较NEG指令)
XORDST,SRC;异或:
用于某些位取反,源数为1的位结果取反
TESTDST,SRC;与测试:
测试某位是否为1,待测位源数设为1,其余位为0
2.移位指令——8条
SHLOPR,CNT;逻辑左移:
右端补0,移出到CF。
CNT为移位次数,默认CL,如果为1可用立即数
SALOPR,CNT;算术左移:
右端补0,移出到CF
SHROPR,CNT;逻辑右移:
左端补0,移出到CF
SAROPR,CNT;算术右移:
左端补符号位,移出到CF
ROLOPR,CNT;小循环左移:
封闭移位,移出位给CF,同时循环给右端
ROROPR,CNT;小循环右移:
RCLOPR,CNT;大循环左移:
将CF封闭在循环内
RCROPR,CNT;大循环右移:
3.3.4串处理指令8条
1.基本串指令——5条
MOVS;串传送
CMPS;串比较,设置标志;
SCAS;串扫描,在附加段的目的串ES:
DI中找AC中的关键字
LODS;从串取,将源串DS:
SDI内容传送给AL或AX
STOS;存入串,将AL或AX内容传送给目的串ES:
DI
无操作数指令,默认将源串DS:
SI一个字节或字传送到目的串ES:
DI。
SI、DI自动按方向标志、按字节数变址(现在可以明白为什么在第2章把SI、DI叫变址寄存器)。
由于操作数地址默认,数据属性不明,因此以上指令还可以写出操作数(仅仅用于表明数据类型)或指令后跟字母B或W表明操作数的类型属性。
2.与串指令配合的重复前缀——3个
无条件重复前缀:
REP;每次判断和修改CX值,(CX)=0则结束本命令;
相等/为零重复REPE/REPZ;同时判断CX计数器和ZF标志,出现(CX)=0或ZF=0结束命令,显然这种重复用于进行串比较,发现不同就停下。
此命令之后,根据CF是否为零可以知道是否发现了不同,若有不同,根据CX值知道不同的位置。
不等/不为零重复:
REPNE/REPNZ;同时判断CX计数器和ZF标志,出现(CX)=0或ZF=1结束命令,显然这种重复用在串中搜索特定数据,发现相同就停下。
3.串指令与重复前缀的组合使用——7种组合
●无条件重复前缀REP固定与MOVS、LODS、STOS搭配使用,特别是MOVS。
REPMOVSB/MOVSW;本指令之前对SI、DI、CX赋值
REPSTOSB/STOSW;较少使用,可在将串初始化为同一值,DB只能一次
REPLODSB/LODSW;不用,LODS更多在循环中使用
●条件重复前缀不仅靠CX控制重复次数,还判断零标志,所以与其搭配的串指令必定是能够影响标志的SCAS和CMPS。
如果要找不同之处,就用相等重复,想找相同就用不等重复。
REPZCMPSB/CMPSW;使用本指令之前对SI、DI、CX赋值
REPNZCMPSB/CMPSW;使用本指令之前对SI、DI、CX赋值
REPZSCASB/SCASW;使用本指令之前对AC、DI、CX赋值
REPNZSCASB/SCASW;使用本指令之前对AC、DI、CX赋值
3.3.5控制和跳转25条(27条)
1.无条件转移——1条
格式:
JMP目的地址
目的地址五种情况:
段内直接短跳转SHORT标号IP=IP+8位有符号偏移量
段内直接近跳转NEARPTR标号IP=IP+16位有符号偏移量
段内间接跳转WORDPTR段内间接地址IP=EA
段间直接远跳转FARPTR段外标号CS:
IP都改变
段间间接远跳转DWORDPTR段外间接地址CS:
IP都该变
2.条件转移——17条(19条)
只有一种寻址:
段内直接短跳转,目标地址应该在距本指令-128~+127字节以内。
如果需要按条件进行长距离跳转或段间跳转可以结合JMP无条件跳转指令实现。
按标志转移(5对10条):
JZ/JNZ标号;为零/非零转移
JS/JNS标号;为负/非负转移
JO/JNO标号;溢出/无溢出转移
JP/JNP标号;为偶/非偶转移
JC/JNC标号;进位/无进位转移
按无符号数比较结果转移:
JC/JB/JNAE标号;借位、小于、不大于等于则转移
(4条)JNC/JNB/JAE标号;无借位、不小于、大于等于转移
JBE/JNA标号;小于等于、不大于则转移
JNBE/JA标号;不小于等于、大于则转移
按有符号数比较结果转移:
JL/JNGE标号;小于、不大于等于则转移
(4条)JNL/JGE标号;不小于、大于等于则转移
JLE/JNG标号;小于等于、不大于则转移
JNLE/JG标号;不小于等于、大于则转移
测试CX=0转移:
JCXZ标号;
3.循环指令(默认CX为循环次数计数器)——3条
LOOP标号;无条件循环,只受CX次数控制
LOOPZ/LOOPE标号;条件循环,次数和零标志双重控制,出现不等则中止
LOOPNZ/LOOPNE标号;条件循环,次数和零标志双重控制,出现相等则中止
寻址特点:
源于条件跳转,所以只有段内直接短跳转,范围-128~+127
4.子程序调用和返回——2条
格式:
CALLDST;子程序调用指令
RET;返回指令(还有一种特殊用法“RET立即数”。
P.100和P.207)
CALL指令操作数四种,决定入栈保存的内容不同:
CALL本段过程名;段内直接近调用,IP入栈,修改IP
CALL间接地址名;段内间接近调用,IP入栈,间接寻址的内容替换IP
CALL外段过程名;段间直接远调用,CS:
IP入栈,直接地址替换CS:
IP
CALL本段过程名;段间间接远调用,CS:
IP入栈,间接地址替换CS:
IP
RET指令只有一种形式,但是用于不同属性(NEAR或者FAR)的子程序结尾引起的操作不同,用于NEAR子程序结尾是只恢复IP(从栈顶弹出1个字),用于FAR子程序结则尾将CS:
IP都恢复(从栈顶弹出2个字)。
5.中断调用和返回
特点:
典型的“段间间接远调用”,调用时依次将PSW、CS、IP入栈,返回时弹回三值。
格式:
INT中断类型号;中断调用
IRET;中断返回
中断是一种I/O方式(与查询并列),正宗应用在于外设I/O,由硬件引发中断。
但是8086中将中断方式应用于软件,设计了中断调用指令。
引起中断的信号称为中断源,按中断源可将中断分为:
硬中断──外中断(外设中断)
软中断──内中断(指令中断)
中断实质:
CPU停下当前程序,转到中断服务程序执行,执行完毕回到断点继续执行。
子程序调用的位置是固定的、子程序是用户自编的。
硬中断的发生是随机的,软中断是写在程序固定位置的(与CALL一样是固定的),中断服务程序是操作系统提供的。
3.3.6处理机指令(12条)
1.标志处理指令——7条
CLC;进位标志清零
CMC;进位标志取反
STC;进位标志置1
CLD;方向标志清零(增址)
STD;方向标志置1(减址)
CLI;中断标志清零(禁止中断)
STI;中断标志置1(允许中断)
2.处理机控制指令——5条
NOP;无操作、空操作
HLT;停机、暂停等待(等待中断)
WAIT;空转等待(等待中断)
ESC;换码
LOCK;封锁(维持总线状态)
3.3.7关于标志设置(第2章讲的PSW中的6个标志)
6个标志中的SF、PF、AF、ZF设置和运用都很简单。
CF的设置也很简单,OF设置稍复杂一点,尤其在引用的时候需要特别注意。
1.加法的CF和OF
CF──用于中间字节表示进位,出现于最高字节表示无符号数溢出;
OF──有符号数溢出:
两数异号相加永不溢出;同号数相加的结果变号则溢出。
2.减法的CF和OF
CF──用于中间字节表示借位,出现于最高字节表示无符号数溢出;
OF──有符号数溢出:
两数同号相减永不溢出;异号数相加的结果与减数同号则溢出。
3.乘法的CF和OF
乘法仅对CF、OF有影响,对其它标志无意义。
MUL:
乘积的高一半为0,则CF=OF=0;乘积的高一半非0,则CF=OF=1;
IMUL:
乘积的高一半为低一半的符号扩展,则CF=OF=0;否则CF=OF=1。
4.除法
对一切标志无定义
3.3.8JMP、CALL、INT指令比较
指令
名称
寻址方式
入栈保存
返回
其它
JMP
无条件转移
段内直接──修改IP
段内间接──替换IP
段间直接──替换CS:
IP
段间间接──替换CS:
IP
不保存
不返回
(没记住从哪来的!
)
进入分支程序
CALL
子程序调用
[CS入栈]
IP入栈
RET返回:
栈顶给IP
[栈顶给CS]
调用自编过程
INT
中断调用
默认段间间接──替换CS:
IP
PSW入栈
CS入栈
IP入栈