1.MOV传送指令
MOV传送指令是双操作数指令,SRC为源操作数,DST 为目的操作数。要求两个操作数属性必须一致,两个操作数不能同时为存储单元。MOV将源操作数传送到目的操作数。
格式: MOV DST,SRC
执行的操作: (DST)←(SRC)
注意:对段寄存器赋值时,源操作数可以用寄存器或存储单元,但不能用立即数;而且代码段寄存器CS不允许用户赋值。目的操作数的属性可以用PTR伪指令指出。
2.数据交换指令XCHG
XCHG指令是双操作数指令,指令的功能是将两个操作数的内容互换。要求必须有一个操作数是寄存器,而且两个操作数的属性必须一 致。操作数不能为立即数。
格式: XCHG OPR1, OPR2
执行的操作: (OPR1) →(OPR2 )
3.进栈和出栈指令
格式: PUSH SRC
执行的操作: (SP) ←(SP)-2,((SP) +1, (SP))←(SRC)
功能:先将堆栈指针SP减2,再将操作数SRC入栈。要求SRC必须是字。
格式: POP DSI
执行的操作: (DST) ←((SP) +1,(SP)),(SP)←(SP) +2
功能:将堆栈指针所指字单元的内容弹到操作数DST中,再将SP加2。
例如:已知( AX) = 95E3H,(BX)=1986H, (SP) =0010H, (SS) = 1250H,将AX、BX压栈保存。接着执行若干指令后,再出栈。
PUSH AX
PUSH BX
MOV AX,0
MOV BX,1
POP BX
POP AX
在执行出栈指令之前,AX寄存器和BX寄存器已经被改变为0和1,但是由于它们的原值已经存在堆栈中了,因此可以很容易地恢复。
4.查表转换指令XLAT
格式: XLAT
执行的操作: (AL)←( (BX) + (AL))
数据表的首地址放入BX,要查找的单元的相对地址(位移量)由AL指出。
在BX为表首地址的内存表中查找相对地址为AL的单元,取出其中的内容再放入AL中。即把AL中的位移量换成对应的存储单元中的内容。
1. LEA有效地址传送指令
格式: LEA寄存器,存储单元
将存储单元的有效地址传送给寄存器。其作用与伪指令0FFSET操作符的作用一样。
例如:
LEA BX,TABLE
LEA DX,[BX]
LEA BX,COUNT[SI]
2.LDS数据段地址传送指令
格式: LDS寄存器,双字存储单元
将双字单元中的低字送人寄存器,高字传送给DS数据段寄存器。
例如:
已知( DS)= 1300H, (BX) =0032H, (13032H) =3504H, (13034H) = 2936H
执行指令: LDS SI, [BX]
源操作数有效地址EA=(BX)=0032H
物理地址=(DS)x10H+EA=1300Hx10H+0032H=13032H
存储单元中的第一个字为 3504H,送人SI,第二个字是2936H,送人DS。
3.LES附加段地址传送指令
格式: LES寄存器,双字存储单元
将双字单元中的低字送人寄存器,高字传送给ES附加段寄存器。
1.CBW字节扩展为字指令
将AL扩展到AX。 如果AL的符号位为0,则AH为0,如果AL的符号位为1,则(AH) = FFH。
2. CWD字扩展为双字指令
将AX扩展到DX。如果AX的符号位为0,则DX为0,如果AX的符号位为1,则(DX)=FFH。
1. ADD加法指令
格式: ADD DST, SRC
执行的操作: (DST) ←(DST) + (SRC)
目的操作数和源操作数相加,结果再放人目的操作数DST。
2.ADC带进位加法指令
格式: ADC DST, SRC
执行的操作: (DST) ←(DST) + (SRC) +CF
目的操作数加上源操作数再加上进位标志CF,结果放人目的操作数DST。
ADC带进位加法指令一般用在双精度加法操作中。当两个低字相加后,两个高字相加时要考虑来自低字的进位,把产生的进位加上。
3.INC加1指令
格式: INC OPR
执行的操作: (OPR) ←(OPR) + 1
类似于C语言的自加操作。
1. SUB减法指令
格式: SUB DST, SRC
执行的操作: (DST) ←(DST) - (SRC)
目的操作数减去源操作数,结果再放入目的操作数DST。
2.SBB带借位减法指令
格式: SBB DST, SRC
执行的操作: (DST) ←(DST) -(SRC) - CF
目的操作数减去源操作数后再减去进位标志CF,结果放入目的操作数DST。
SBB带借位减法指令一般用在双精度减法操作中。当两个低字相减后,有可能向高位借位,因此两个高字相减时要考虑来自低字的借位,要把产生的借位也减掉。
3.DEC减1指令
格式: DEC OPR
执行的操作: (OPR) ←(OPR) -1
相当于C语言的自减操作
4. NEG求补指令
格式: NEG OPR
执行的操作: (OPR)←0- (OPR)
相当于求补操作
说明:对正数的补码求补变为其负数的补码,对负数的补码求补变为其正数的补码。利用NEG指令可以求负数的绝对值。
5. CMP比较指令
格式: CMP 0PR1, 0PR2
执行的操作: (OPR1) - ( OPR2 )
将两个操作数作相减运算,结果不回送,改变标志位。通常后跟条件转移指令,根据CMP比较之后标志位的值进行转移。
1. MUL无符号数乘法指令
2.IMUL带符号数乘法指令
与无符号数乘法指令格式–样,但是指令的操作码改为IMUL。执行带符号数乘法指令时,系统将把操作数作为补码进行运算。
3.DIV无符号数除法指令
除法指令也是单操作数指令。字节除法的16位被除数默认在AX中,8位除数在指令中;字除法的32位被除数默认在DX、AX中,16 位除数写在指令中。
4. IDIV带符号数除法指令
指令的操作码为IDIV。指令格式与无符号数除法一样。 执行带符号数除法指令时,系统把操作数作为带符号数补码进行运算,商和余数也都是带符号数。
注意 :无论是无符号数除法还是带符号数除法,都要考虑溢出问题。对字节除法,如果被除数AX中AH的绝对值≥8位除数SRC的绝对值;或者对字除法,被除数DX、AX中DX的绝对值≥16位除数SRC的绝对值,商就会产生溢出。这时系统会进入0号除法溢出中断进行处理。
8086系统并没有提供十进制运算指令,前面学习的加减乘除指令都是针对二进制而言的。由于BCD码是用二进制编码来表示十进制数,因此计算机实际上进行的还是二进制运算。例如,十进制运算5 +7=12,用BCD码表示为0101 +0111。 按照二进制相加,结果等于1100,而这个结果不是BCD码;那么再把它加6,结果就是00010010,即BCD码表示的12。通过观察二进制数运算结果和对应的十进制运算结果的差别可知,只要是结果大于9,就应该对计算结果做修正调整,这样获得的数值就符合逢十进一的十进制运算规则。
注意:调整指令要紧跟在加减乘运算指令之后。对于加、减、乘运算,要先计算再调整;而对于除法运算,则要先调整被除数再计算。由于调整指令是对AL或AX寄存器中的值进行调整,因此要把运算结果放在AL或AX中后再执行调整。如果用压缩BCD码,只能做加法和减法运算调整。
1.压缩的BCD码加法调整
格式: DAA
如果AL的低4位大于9,则将AL加6,并将辅助进位标志AF置1。如果AL的高4位大于9 (或等于9、同时辅助进位AF为1),将AL加60H,并将进位标志CF置1。此时CF=1,可看作百位上的1。
2.压缩的BCD码减法调整
格式: DAS
如果辅助进位AF为1 (AC), 则将AL减6,AF 置1。如果AL的高4位大于9,将AL减60H,并将CF置1。
3.非压缩的BCD码加法调整
格式: AAA
如果AL的低4位大于9,将AL加6、AH加1,AL的高4位清零、CF与AF置1。由于非压缩的BCD码用1个字节表示1个十进制数,调整后若加上30H就是该数值的ASCII码,所以AAA的含义为加法执行后可调整为ASCII。
注意: AAA指令适用于百位以内的加法运算调整;如果运算结果超过百位(200 以内),则需要用其他方法调整。
4.非压缩的BCD码减法调整
格式: AAS
如果辅助进位AF为1 (AC), 将AL减6、AH减1,AL的高4位清零、CF置1。
5.非压缩的BCD码乘法调整
格式: AAM
将乘积AX调整为两个非压缩的BCD码。AL除以CAH,得到的商送AH,余数送入AL。即乘积的高位数在AH、低位数在AL中。
注意:乘积不能超过99
6.非压缩的BCD码除法调整
格式: AAD
在做除法之前,将被除数AX中的两个非压缩的BCD码调整为二进制数。
(AL)=(AL) +(AH) x10, AH清零。除法运算之后,商在AL、余数在AH中。
上篇 详解伪指令
参考书籍:《汇编语言》第二版 郑晓薇