汇编语言学习指令——加减运算指令

 1、加法指令ADD

格式:ADD OPRD1,OPRD2

(OPRD1) = (OPRD1)+(OPRD2)

例如:MOV AX,7896H;   AX=7896H

即AH = 78H, AL=96H;各个标志寄存位保持不变

ADD AL,AH   ;AL=0EH,AH = 78H,即AX = 780EH(0111100000001110)

此时如果FLAG寄存器的值分别为

CF = 1, ZF = 0,SF = 0,OF = 0,AF = 0,PF = 0

继续操作如下:

ADD DX,0F0F0H

执行前(DX) = 4652H,执行后(DX)=3742H,ZF=0,SF=0,CF=1,OF=0

如果执行如下操作:

ADD AX,4321H

执行前(AX)=62A0H,执行后(AX)=A5C1H SF=1,ZF=0,CF=0,OF=1

讲解一下执行的过程,为什么FLAG标志位的状态发生了变化。
在寄存器中一般数值都是用补码表示,最高位代表符号位。
但是在加法指令中,是不区分操作数的符号位的,因为补码的表示完全避开了这个符号位的概念<在下一篇目录中会有说明>,符号的概念只在编程语言级别才有区分(针对加法和减法)

根据上面的分析可以知道:加法指令影响标志位。

PF标志位表示结果包含的1的个数,如果为偶数个则为1,如果是奇数个则为0


2、带进位的加法指令ADC( ADD with carry )
格式如下:
ADC,OPRD1,OPRD2
OPRD1 = OPRD1+OPRD2+CF
例如:下列指令序列执行了两个双精度的加法。(双精度32位)
设目的操作数放在DX和AX寄存器中,其中DX存放高位字,AX存放低位字
源操作数放在BX,CX中,其中BX存放高位字
(DX) = 0002H (AX) = 0F365H
(BX) = 0005H (CX) = 0E024H
指令序列如下:
ADD AX,CX
ADC DX,BX
执行第一条指令后:
AX = 0D389H(1101001110001001),SF=1, ZF=0,CF=1,OF=0
执行第二条指令后:
DX = 00008H(0000000000001000),SF=0,  ZF=0, CF=0, OF=0

从上面的例子可以看到:
为了实现双精度数的加法,必须用两条指令来完成,低位和低位相加,
产生进位,然后再使用ADC。
另外带符号的双进度数的溢出,需要根据ADC指令的OF来判断
ADD指令的OF没有作用。
通过上面例子可以看出:影响FLAG

3、加1指令INC(INCrement)
加1指令的格式如下:
INC OPRD
OPRD = OPRD + 1;
操作数可以是通用寄存器,也可以是存储单元
这条指令的执行结果影响标志位ZF,SF,OF,PF和AF,但它不影响CF
该指令主要用于调整地址指针和计数器。

 

两个数相加,如果最高有效位不同,那么肯定不会发生溢出,即OF=0,但是会有进位,CF的值根据是否有进位来判断

如果最高有效位相同,相加的结果的最高有效位如果与操作数相反,那么肯定有溢出了,则OF=1,证明发生了错误,CF的值根据是否有进位来判断

在高级的编程语言层面,这个就作为“截断”进行处理,然后可以根据OF和CF的值来判断结果是错误,还是正确。

如果OF = 1,则结果肯定是错误,不用理会CF

如果OF = 0,则结果可能是正确的,如果CF=0,则正确,如果CF=1,则发生了进位,结果被“截断”

 

4、减法指令SUB(SUBtraction)
格式如下:
SUB OPRD1,OPRD2
执行的操作:(OPRD1) = (OPRD1)-(OPRD2)
例如:
SUB [SI+14H],0136H
指令执行前 (DS) = 3000H, (SI)=0040H
(300054H) = 4336H
指令执行后 (30054H) = 4200H
SF=0, ZF=0, CF=0, OF=0

例子如下:
SUB DH,[BP+4]
指令执行前
(DH)=41H,(SS)=0000H,(BP)=00E4H,(000E8H)=5AH
指令执行后
(DH)=E1H,(SS)=0000H,(BP)=00E4H,(000E8H)=5AH
SF=1, ZF=0, CF=1<借位>, OF=0

 

5、带借位的减法SBB( SuBtrace with Borrow)
与带借位的加法刚好相反
SUC OPRD1,OPRD2
OPRD1 = OPRD1-OPRD2-CF
例如:
SBB AL,DL
SBB DX,AX
该条指令主要用于多字节想减的场合。

6、减1指令 DEC(DECrement)
格式如下:
DEC OPRD
(OPRD) = (OPRD)-1
例如:
DEC VARB  ;VARB是字节变量
操作数OPRD可以是通用寄存器,也可以是存储单元。
减1指令,在相减的时候,把操作数作为一个无符号数对待。
这条指令执行的结果影响ZA,OF,PF,SF,AF但是不影响CF
该条指令主要用于调整地址指针和计数器。

 

两个操作数相减,如果最高有效位相同,则不会发生溢出,则OF=0,CF根据是否借位来判断,如果CF=1,则借位,如果CF=0,则没有借位。

如果最高有效位不同,且操作的结果和减数的最高有效位相同,则OF=1,CF根据是否借位来判断,如果CF=1,则借位,如果CF=0,则没有借位

 

7、取补指令NEG(NEGate)
格式如下:
NEC OPRD
这条指令对操作数取补,就是用零减去操作数OPRD,在把结果送到OPRD中
(OPRD) = -(OPRD)
操作数可以是通用寄存器,也可以是存储单元
此指令的执行结果影响CF/ZF/SF/OF/AF和PF
操作数为0时,求补的运算结果是CF=0,其它情况则均为1,都是借位操作
如果在字节操作的时候对-128取补,或在字操作的时候对-32768取补,则操作数不变,但是OF被置为1,

其它都是0

 

8、比较指令CMP(CoMPare)
格式如下:
CMP OPRD1,OPRD2
这条指令完成操作数OPRD1减去OPRD2,运算结果不送到OPRD1,
但是影响标志CF/ZF/SF/OF/AF和PF
记住双操作数中至少有一个寄存器。
比较指令主要用于比较两个数的关系,是否相等,谁大谁小
执行了比较指令后,可以根据ZF是否置位,来判断两者是否相等
如果两者都是无符号数,则可以根据CF判断大小,如果借位了则前者小
如果两个都是有符号数,则可以根据SF和OF判断大小,

若为无符号数,则根据CF判断大小:
若CF = 1,则OPRD1 < OPRD2
若CF = 0,则OPRD1 >=  OPRD2,如果ZF不等于1则是大于


若为有符号数,则根据SF和OF判断大小:
若SF = 1, OF = 1,则OPRD1 > OPRD2,说明发生了溢出,相减后为负数1(正数-负数)
若SF = 1, OF = 0,则OPRD1 < OPRD2,说明没有发生溢出,相减后为负数
若SF = 0, OF = 1,则OPRD1 < OPRD2,说明发生了溢出,相减后为正数,但是发生了溢出(负数-正数)
若SF = 0, OF = 0,则OPRD1 > OPRD2,说明正常操作,且结果为正数

 

 

在汇编指令中,是不区分有符号数和无符号数,但是汇编指令中对于加减法指令是不区分有符号数和无符号数的。

但是乘除法指令是区分有符号数和无符号数。


 

 

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值