汇编指令手册.docx
《汇编指令手册.docx》由会员分享,可在线阅读,更多相关《汇编指令手册.docx(29页珍藏版)》请在冰点文库上搜索。
![汇编指令手册.docx](https://file1.bingdoc.com/fileroot1/2023-4/29/cf6d9426-98ec-4570-a1e4-fb80d865550b/cf6d9426-98ec-4570-a1e4-fb80d865550b1.gif)
汇编指令手册
8086/8088指令系统
8086/8088的指令系统丰富,而且指令的功能也强。
大多数指令既能处理字数据,又能处理字节数据;
算术运算和逻辑运算不局限于累加器,
存储器操作数也可直接参加算术逻辑运算。
8086/8088的指令系统可分为如下六个功能组:
(1)数据传送
(2)算术运算
(3)逻辑运算
(4)串操作
(5)程序控制
(6)处理器控制
汇编语言语句的一般格式。
指令语句可由四部分组成,一般格式如下:
[标号:
]指令助记符[操作数1][操作数2][;注释]
指令是否带有操作数,完全取决于指令本身标号的使用取决于程序的需要,
标号只被汇编程序识别,它与指令本身无关。
(一)数据传送指令
数据传送指令组又可分为:
传送指令,交换指令,地址传送指令,堆栈操作指令,标志传送指令,查表指令,输入输出指令在有关章节介绍。
除了SAHF和POPF指令外,这组指令对各标志没有影响。
1,传送指令
其格式如下:
MOVDST,SRC
目的,源
源操作数可以是累加器,寄存器,存储单元以及立即数,
而目的操作数可以是累加器,寄存器和存储单元。
传送不改变源操作数。
传送指令能实现下列传送功能:
(1)CPU内部寄存器之间的数据传送。
例如:
MOVAH,AL
MOVDL,DH
MOVBP,SP
MOVAX,CS
注意:
源和目的操作数不能同时是段寄存器;代码段寄存器CS不能作为目的;指令指针IP即不能作为源,也不能作为目的。
注意,这种例外永远存在。
(二)交换指令
利用交换指令可方便地实现通用寄存器与通用寄存器或存储单间的数据交换,
交换指令的格式如下:
XCHGOPRD1,OPRD2
此指令把操作数OPRD1R的内容与操作数OPRD2的内容交换。
操作数同时是字节或字。
例如:
XCHGAL,AH;XCHGSI,BX
OPRD1和OPRD2可是通用寄存器和存储单元。
但不包括段寄存器,也不能同时是存储单元,还不能有立即数,可采用各种存储器寻址方式来指定存储单元。
例如:
XCHGBX,[BP+SI]如指令执行前:
(BX)=6F30H,(BP)=0200H,(SI)=0046H,(SS)=2F00H,(2F246)=4154H
物理地址=2F000+0200+0046=2F246H
指令执行后:
(BX)=4154H(2F246H)=6F36H
此指令不影响标志位
(三)地址传送指令
80686/8088有如下三条地址传送指令。
(1)指令LEA(LoadEffectiveAddress)
指令LEA称为传送有效地址指令,其格式如下:
LEAREG,OPRD
该指令把操作数OPRD的有效地址传送到操作数REG
操作数OPRD必须是一个存储器操作数,
操作数REG必须是一个16位的通用寄存器。
例如:
LEAAX,BUFFER;BUFFER是变量名
LEADS,[BS+S]
LEASL,[BP+DI+4]
例如:
LEABX,[BX+SI+0F62H]
如指令执行前(BX)=0400H,(SI)=003CH
指令执行后(BX)=0040+003C+0F62=139EH
(2)指令LDS(LoadpointerintoDS)
段值和段内偏移构成32位的地址指针。
该指令传送32位地址指针,其格式如下:
LDSREG,OPRD
执行的操作:
(REG)←(SRC)
(DS)←(SRC+2)
该指令把操作数OPRD中所含的一个32位地址指针的段值部分送到数据段寄存器DS,把偏移部分送到指令给出的通用寄存器REG。
操作数OPRD必须是一个32位的存储器操作数,
操作数REG可以是一个16的通用寄存器,但实际使用的往往是变址寄存器或指针寄存器。
LDSSL,POINTER;POINTER是一个双字变量
假设双字变量POINTER包含的32位地址指令的段值为5678H,偏移为1234H,那么在执行指令后:
(DS)=5678H,(SI)=1234H
32位地址指针的偏移部分存储在双字变量的低地址字中,段值部分存储在高地址中。
例如:
LDSSI,[10H]
如指令执行前:
(DS)=C000H,(C0010H)=0180,(C0012H)=2000H
指令执行后:
(SI)=0180H,(DS)=2000H
(3)指令LES(LoadpointerintoES)
LES指令也传送32位地址指针,其格式如下:
LESREG,OPRD
该指令把操作数OPRD中包含的32位地址指针的段值送到附加段寄存器ES,
把偏移部分送到指令给出的通用寄存器REG。
执行的操作:
(REG)←(SRC)
(ES)←(SRC+2)
例如:
LESDI,[BX]
如指令执行前:
(DS)=B000H,(BX)=080AH,(0B080AH)=05AEH,(0B080CH)=4000H
执令执行后(DI)=05AEH,(ES)=4000H
(四)堆栈操作指令
在80686/8088系统中,堆栈是一段RAM区域.
称为栈底的一端地址比较大,称为栈顶的一端比较小.
(高地址)(低地址)
堆栈的段值在堆栈段寄存器SS中,
堆栈指针寄存器SP始终指向栈顶.
堆栈是以”后进先出”的方式工作的一个存储区.
堆栈的存取必须以字为单位.
堆栈操作指令分为两种:
(1)进栈指令
格式如下:
PUSHSRC
执行的操作:
(SP)←(SP)-2
该指令把源操作数SRC压入堆栈.它先把堆栈指针寄存器SP的值减2,然后把源操作数SRC送入由SP所指指的栈顶.
源操作数SRC可以是通用寄存器和段寄存器,可以是字存储单元.
例如:
PUSHAX
假设AX=2107H
(2)出栈指令POP
格式如下:
POPDST
执行的操作:
(SP)←(SP)+2
POPDST
该指令从栈顶弹出一个字数据到目的操作数DST.
它先把堆栈指针寄存器SP所指的字数据送至目的操作数DST,然后SP值加2.
DST可以是通用寄存器和段寄存器(但CS例外),也可是字存储单元.
(五)标志传送指令
(1)标志传送指令
标志传送指令属于数据传送指令组.
1,指令LAHF(LoadAHwithFlags)
指令LAHF采用固定寻址方式,指令格式如下:
LAHF
该条指令把标志寄存器的低8位(包括SF,ZF,AF,PF和CF)传送到寄存器AH的指定位,
如下图所示:
这条指令本身不影响这些标志和其他标志.
2,指令SAHF采用回定寻址方式,其格式如下:
SAHF
这条指令与指令LAHF刚好相反,
把寄存器AH的指定位送至标志寄存器低8位的SF,ZF,AF,PF和CF标志位.
因而这些标志的内容就要受到影响,并取决于AH中相应位的状态.
但这条指令不影响溢出标志OF,方向标志DF,中断允许标志IF和追踪标志TF,也即不影响标志寄存器的高位字节.
例如:
MOVAH,0C1H
SAHF;CF=1,PF=0,AF=0,ZF=1,SF=1
3,指令PUSHF
指令PUSHF的格式如下:
PUSHF
该条指令把标志寄存器的内容压入堆栈,即先把堆栈指针寄存器SP的值减2,然后把标志寄存器的内容送入由SP所指的栈顶.
4,指令POPF
指令POPF的格式如下:
POPF
该条指令把当前堆栈顶的一个传送到标志寄存器,同时相应地修乞讨堆栈指针,即把堆栈指针寄存器SP的值加2.
这条指令和PUSHF指令一起可以保存和恢复标志寄存器的内容,即保存和恢复各标志的值.另外,这两条指令也可以用来改变追踪标志TF.
为了改变TF标志,可先用PUSHF指令将标志压入堆栈,然后设法改变栈顶字单元中的第8位(把整个标志寄存器看成是一个字),再用POPF指令把该字弹回到标志寄存器,这样其余的标志不受影响,而只有TF标志按需要改变了.
(2)标志位操作指令
标志位操作指令公对指令规定的标志
产生指令规定的影响,对其他标志没有影响.
产生指令规定的影响,对其它标志没有影响.
1,清进位标志CLC(ClearCarryflag)
清进位标志指令的格式如下:
CLC
该指令使进位标志为0.
2,置进位标志指令STC(SeTCarryFlag)
置进位标志指令的格式如下:
STC
该指令使进位标志为0.
3,进位标志取反指令CMC(CoMpleinentcarryflag)
进位标志取反指令的格式如下:
CMC
该指令使进位标志取反.如CF为1,则使CF为0;如CF为0,则CF为1.
4,清方向标志CLD(ClearDirectionflag)
清方向标志指令的格式如下:
CLD
该条指令使主向标志DF为0.
从而在执行串操作指令时,使地址按递增方式变化.
5,置方向标志STD(SeTDirectionflag)
置方向标志指令的格式如下:
STD
该条指令使方向标志DF为1,从而在执行串操作指令进,使地址按递减方式变化.
6,清中断充许标志CLI(CleraInterruptenableflag)
清中断允许标志指令的格式如下:
CLI
该条指令使中断允许标志IF为0,于是CPU就不响应来自外部装置的可屏蔽中断.但对不可屏蔽中断和内部中断都没有影响.
7,置中断允许标志STI(SeTInterruptenableflag)
置中断允许标志指令的格式如下:
STI
该条指令使中断允许标志IF为1,则CPU可以响应可响应屏蔽中断.
(六)加减运算指令
(1)加法指令ADD
格式如下:
ADDOPRD1,OPRD2
执行的操作:
(OPRD1)←(OPRD1)+(OPRD2)
例如:
MOVAX,7896H;AX=7890H
即AH=78H,AL=96;各标志保持不变
ADDAL,AH;AL=0EH,
AH=78H,即AX=780EH
;CF=1,ZF=0,SF=0,OF=0,AF=0,PF=0
例如:
ADDDX,0F0F0H
执行前(DX)=4652H
执行后(DX)=3742HZF=0,SF=0,CF=1,OF=0
例如:
ADDAX,4321
执行前(AX)=62A0
执行后(AX)=A5C1HSF=1,ZF=0,CF=0,OF=1
从上面的例子可看出:
加法指令影响标志位
OF位则根据操作数的符号及其变化情况来设置:
若两个操作的符号相同而结果的符号与相反时OF=1,否则OF=0
CF位可以用来表示无符号数的溢出,由于无符号数的最高有效位只有数值意义而无符号意义,所以从该位产生的进位应该是结果的实际进位值,但是有限数的范围内就说明了结果。
(1)带进位加法指令ADD(AddwithCarry)
带进位加法指令的格式如下:
ADCOPRD1,OPRD2
OPRD1←OPRD1+OPRD2+CF
例如:
下列指令序列执行两个双精度的加法.
设目的操作数放在DX和AX寄存器,
其中DX存放高位字.源操作数存放在BX,CX中,其中BX存放高位字.
如指令执行前:
(DX)=0002H,(AX)=0F365H
(BX)=0005H,(CX)=0E024H
指令序列为:
ADDAX,CX
ADCDX,BX
执行第一条指令后:
(AX)=0D389H,SF=1,ZF=0,ZF=1,OF=0
执行第二条指令后:
(DX)=0008H,SF=0,ZF=0,CF=0,OF=0
则该指令序列执行完后(DX)=0008H,(AX)=D389H
(3)加1指令INC(INCrement)
加1指令的格式如下:
INCOPRD
这条指令完成对操作数OPRD加1,然后把结果送回OPRD,即:
OPRD←OPRD+1
操作数OPRD可以是通用寄存器,也可以是存储单元.
这条指令执行的结果影响标志ZF,SF,OF,PF和AF,但它不影响CF.
该指令主要用于调整地址指针和计数器.
例如:
写出把首地址为BLOCK的字数组的第6个字送到DX寄存器的指令.
要求使用以下几种寻址方式:
1.寄存器间接寻址MOVBX,OFFSETBLOCK
ADDBX,000AHMOVDX,[BX]
2,寄存器相对寻址MOVBX,OFFSETBLOCK
MOVDX,[BX+000AH]
(3)减法指令SUB(SUBtraction)
减法指令的格式如下:
目的源
SUBOPRD1,OPRD2
执行的操作:
(OPRD1)←(OPRD1)-(OPRD2)
例如:
SUB[SI+14H],0136
指令执行前(DS)=3000H,(SI)=0040H,(30054H)=4336
指令执行后(30054H)=4200H
SF=0,ZF=0,CF=0,OF=0
例如:
SUBDH,[BP+4]
指令执行前(DH)=40H,(SS)=0000H,(BP)=00E4H,(000E8H)=5AH
指令执行后(DH)=0E7H,SF=1,ZF=0,CF=1,OF=0
此指令影响标志位CF位说明无符号数想减的溢出,同时它又是被减数的最高有效位向高位的借位,OF位则说明带符号的溢出.
减法的OF位的设置方法为:
若两个数的符号相反,而结果的符号与减数相同则OF=1,说明结果是错误的.
(4)带借位减法指令SBB(SuBtractwithBorrow)
带借位指令的格式如下:
SBBOPRD1,OPRD2
执行的操作:
(OPRD1)←(OPRD1)-(OPRD2)-CF
例如:
SBBAL,DL
SBBDX,AX
该指令主要用于多字节相减的场合
(5)减1指令DEC(DECreinent)
减1指令的格式如下:
DESOPRD
执行的操作:
(OPRD)←(OPRD)-1
例如:
DECVARB;VARB是字节变量
操作数OPRD可以是通用寄存器,也可以是存储单元。
在相减时,把操作数作为一个无符号数对待。
这条指令执行的结果影响标志ZF,SF,OF,PF和AF,但不影响CF。
该指令主要用于调整地址指针和计数器。
(6)取补指令NEG(NEGate)
取补指令的格式如下:
NEGOPRD
这条指令对操作数取补,就是用零减少操作数OPRD,再把结果送回OPRD。
执行的操作:
(OPRD)←0-(OPRD)
例如:
NEGAL
NEGVARW[SI];有效地址就是VARW的位移加SI的值。
如在字节操作时对取补,或在字操作时对-32768取补,则操作数不变,
但OF被置为1。
其它均为何0。
操作数可以是通用寄存器,也可以是存储单元。
此指令的执行结果影响CF,ZF,SF,OF,AF和PF,操作数为0时,求补运算的结果使CF=0,其它情况则均为1。
(7)比较指令CMP(CoMPare)
比较指令的格式如下:
CMPOPRD1,OPRD2
这条指令完成操作数OPRD1减去操作数OPRD2,运算结果不回送到OPRD1。
但影响标志CF,ZF,SF,OF,AF和PF。
例如:
CMPSL,DI
CMPCL,5
CMPDX,[BP-4]
比较指令主要用于比较两个数的关系,是否相等,谁大谁小。
执行了比较指令后,可根据ZF是否置位,判断两者是否相等。
如果两者是无符号数,则可根据CF判断大小;
如果两者是有符号数,则要根据SF和OF判断大小。
(七)乘除运算指令
乘除运算指令分为无符号运算和有符号数运算指令,这点与加减运算指令不同。
乘除运算指指令对标志位的影响有些特别。
(1)乘法指令
在乘法指令中,一个操作数总是隐含在寄存器AL(8位数相乘)或者AX(16位数相乘)中,另一个操作数可以采用除立即数方式以外的任一种寻址方式。
1,无符号乘法指令MUL(MULLtiply)
无符号指令的格式如下:
MULOPRD
在乘法指令里,目的操作数必须是累加器。
两个8位数相乘得到的是16位乘积存放在AX中,两个16位数相乘得到的是32位乘积存放在DX,AX中,DX存放放高位字,AX存放低位字。
如果乘积结果的高半部分(字节相乘时为AH,在字相乘时为DX)不等于零,则标志CF=1,OF=1,否则CF=0,OF=0。
所以如果CF=1和OF=1表示在AH或DX中含有结果的有效数,
该指令对其它标志位无定义。
2,有符号数乘法指令IMUL(sIgnedMULtiply)
有符号数乘法指令的格式如下:
IMULOPRD
这条指令把被乘数和乘数均作为有符号数,此外与指令MUL完全类似。
如果乘积结果的高半部分(字节相乘时为AH,在字相乘时为DX)不是低半部分的符号扩展,则标志CF=1,OF=1;
否则CF=0,OF=0。
所以如果CF=1和OF=1表示在AH或DX中含有结果的有效数。
该指令对其字标志位无定义。
例如:
如(AL)=0B4H,(BL)=11H赤执行指令
IMULBL和MULBL后的乘积值
(AL)=0B4H为无符号的180D,带符号数的-76D
(BL)=11H为无符号数的17D,带符号数的17D
执行IMULBL的结果为(AX)=0FAF4H=-1292D
执行MULBL的结果为(AX)=0BF4H=3606D
(2)除法指令
在除法指令中,被除数总是在隐含在寄存器AX(除数是8位)或者DX和AX(除数是16位)中,另一个操作数可以采用除立即数方式外的任一种寻址方式。
1,无符号数除法指令DIV(DIVision)
无符号数除法指令的格式如下:
DIVOPRD16位8位
字节操作表示为:
(AL)←(AX)/(OPRD)的商;(AH)←(AX)/(OPRD)的余数
字操作表示为:
(AX)←(DX,AX)/(OPRD)的商;(DX)←(DX,AX)/(OPRD)的余数。
2,有符号数除法指令IDIV(SignedDIVision)
有符号数除法指令的格式如下:
IDIVOPRD
这条指令把被除数和除数均作为有符号数,此外与指令DIV完全类似。
当除数为0,或者商太大
(字节除时超过127,字除时超过32767)
(字节除时小于-127,字除时小于-32767)
则引起0号中断。
例如:
设(AX)=0400H,(BL)=0B4H,即(AX)为无符号数的1024D,带符号数的1024D,(BL)为无符号的180D,带符号数的-76D
执行DIVBL的结果是:
(AH)=7CH=124D余数
(AL)=05H=5D商
执行IDIVBL的结果是:
(AH)=24H=36D余数
(AL)=0F3H=-13商
(八)逻辑运算和移位指令
(1)逻辑运算指令
1,否操作指令NOT
否操作指令的格式如下:
NOTOPRD
这条指令把操作数OPRD取反,然后送回OPRD。
操作数OPRD可以是通用寄存器,也可以是存储器操作数。
此指令对标志没有影响。
2,与操作指令AND
与操作指令的格式如下:
ANDOPRD1,OPRD2
运算方法:
“与”操作中有一位是1,其结果为0,有两位是1,其结果为1。
这条指令对两个操作数进行按位的逻辑“与”运算,结果送到目的操作数OPRD1。
该指令执行以后,标志CF=0,标志OF=0,标志PF,ZF,SF反映运算结果,标志AF未定义。
某个操作数自己与自己相“与”,则值不变,但可使进位标志CF清0。
与操作指令主要用于在使一个操作数中的若干位维持不变,而另外若干位清为0的场合。
把要维持不变的这些与“1”相与,而把要清为0的这些位与“0”相“与”就能达到这样的目的。
3,或操作指令OR
或操作指令的格式如下:
OROPRD1,OPRD2
此指令相当于OPRD1+OPRD2。
运算方法:
或操作时有一位是1的其结果为1(和与操作相反)
这格指令执行后,标志CF=0,标志OF=0,标志PF,ZF,SF反映运算结果,标志AF未定义。
某个操作数自已与自己相“或”,则值不变,但可使进位标志清0。
或操作指令主要用在使一个操作数中的若干位维持不变。
而另外若干位位置为1的场全。
把要维持不变的这些位与“0”相“或”,而把要置为1的这些位与“1”相“或”就能达到这样的目的(正好和与操作相反)。
4,异或操作指令XOR
异或指令的格式如下:
XOROPRD1,OPRD2
运算方法:
两位数相同时为0,有一位为0,一位为1时其结果为1
这条指令对两个操作数进行近位的逻辑“异或”运算,结果送到目的操作数OPRD1,该指令执行以后,标志CF=0,标志OF=0,标志PF,ZF,SF反映运算结果,标志AF未定义。
某个操作数自己与自己相“异或”,则结果为0,并可使进位标志CF清0。
异或操作指令主要用在使一个操作数中的若干位维持不变,而另外若干位置取反的场合。
把要维持不变的这些与“0”相“异或”,而把要取反的这些位与“1”相“异或”就能达到这样的目的。
5,测试指令TEST
测试指令的格式如下:
TESTOPRD1,OPRD2
这条指令和指令AND类似,也把两个操作数进行按位“与”,但结果不回送操作数OPRD1。
该指仅执行以后,标志ZF,PF和SF反映运算结果。
标志CF和OF被清0。
该指令通常用于检测某些位是否为1,但又不希望改变原操作数的场合。
例如:
要检AL中的位6或位2是否有一位为1,可以使用如下的指令:
TESTAL,01000100B;符号B表示二进制
(44H)
如果位6和位2全为0,那么执行上面的指令后,ZF被置1,否则ZF被清0。
(2)一般移位指令
1,算术左移或逻辑左移指令SAL/SHL
(ShiftArithmeticLetf/ShiftlogicLeft)
只移位1的话可以直接写,移位多次的话要把移位数放入CL中。
算术左移和逻辑左移进行相同的动作,尽管为了方便提供两个助记符,但只有一条机器指令,具体格式如下:
SALOPRD,M或者
SHLOPRD,M
算术左移SAL/逻辑左移SHI指令把操作数OPRD左移m,每移动一位,左边用0补足,移出的最高位进入标志CF。
例如:
MOVAL,8CH
SHLAL,1;AL=18H,CF=1,PF=1,ZF=0,SF=0,OF=1
MOVCL,6
SHLAL,CL;AL=0,CF-0,PF=1,ZF=1,SF=0,OF=0
移位时要把数值先转换成二进制
只要左移以后的结果未超过一个字节或一个字的表达范围,那么每左移一次,原操作数每一位的权增加了一倍,也即相当于原数乘2。
例如:
实现把寄在器AL中的内容(设为无符号数)乘以10,结果存放在AXKH。
XORAH,AH;(AH)=0
SHLAL,1;2X
MOVBX,AX;暂存2X
SHLAX,1;4X
SHL,AX,1;8X
ADDAX,BX;8X+2X
2,算术右移指令SAR(ShiftArithmeticRight)
算术右移指令的格式如下:
SAROPRD,m
该指令使操作数右移m位,同进每移一位,左边的符号位保持不变,移出的最代位进标位CF。
(无符号数用0补足,有符号数用1补足)
例如:
MOVCL