运算指令(四)


运算指令(四)

单操作数指令都要求操作数:

  • 不能是立即数
  • 若是存储器操作数,需要声明操作数字长

算数运算类指令

算数运算指令执行大多对状态标志位产生影响

  • 加法运算指令
  • 减法运算指令
  • 乘法指令
  • 除法指令

加法运算指令

  • ADD
  • ADC
  • INC

ADD指令

通常用在两个字节或两个字相加的运算环境下
格式:

ADD OPRD1,OPRD2

操作
两个操作数相加最终保存到OPRD1
对所有标志位都有影响
例:

1
2
3
4
MOV AL,78H
ADD AL,99H
六个标志位为:
CF=1 SF=0 AF=1 ZF=0 PF=1 OF=0

ADC指令

ADC多用于多字节数相加,所以要在使用前将CF清零
指令格式,对操作数的要求,对标志位的影响与ADD完全一样
操作:
两个操作数相加之后在加上CF才保存到OPRD1

INC指令

常用于在程序中修改地址指针
格式:

INC OPRD

这个操作数不能是段寄存器立即数
操作数+1保存到OPRD1
INC指令不影响CF

1
2
3
4
5
6
7
8
9
10
11
12
将内存数据中M1为首和M2为首的两个20字节数之和,存入M2为首的区域
LEA SI M1 ;将M1的偏移地址存入SI
LEA DI M2 ;将M2的偏移地址存入DI
MOV CX,20 ;循环20次
CLC ;使CF=0
NEXT:MOV AL,[SI] ;将SI里面的内容作为地址,取这个地址的内容存入AL
ADD [DI],AL ;相加存放到[DI]
INC SI ;地址+1
INC DI ;地址+1
DEC CX ;CX-1
JNZ NEXT ;不为零跳转,为零结束循环
HLT ;暂停执行

减法运算指令

  • SUB
  • SBB
  • DEC
  • CMP
  • NEG

前三个指令对操作数的要求和对标志位的影响与加法指令相同

SUB指令

格式:

SUB OPRD1,OPRD2

操作:
OPRD1减去OPRD2结果存入OPRD1

SBB指令

OPRD1减去OPRD2减去CF结果存入OPRD1
与ADC一样,SBB指令多用于两个多字节数的相减运算

DEC指令

OPRD-1存入OPRD
对操作数的要求和对标志位的影响与INC相同
常用于在程序中修改计数值

CMP指令

用于比较两个数的大小
格式:

CMP OPRD1,OPRD2

操作:
OPRD1-OPRD2
结果只影响标志位,不影响目标操作数
无符号数比较
CMP AX,BX
若AX大于等于BX ,则CF=0
若AX小于BX,则CF=1
若AX等于BX,则CF=0,ZF=1
有符号数比较
OF和SF状态相同,AX大于等于BX
OF和SF状态不同,AX小于BX

NEG指令

格式:

NEG OPRD

操作:
0-OPRD存入到OPRD
对一个负数取补码就相当于用零减去此数

乘除指令

乘除运算指令均是单操作数,采用隐含寻址

乘法指令

乘法运算中,乘积是乘数的双倍字长
乘法指令隐藏了被乘数的累加器AL或AX,以及存放结果的AX或者AX DX

  • 无符号数MUL
  • 有符号数IMUL
无符号MUL

格式:

MUL OPRD

操作数不能是立即数
若OPRD为字节数,则ALOPRD结果存放到AX
若OPRD为16位数,则AX
OPRD结果存放到DXAX
例:

MUL BYTE PTR[BX]

这条指令就是讲BX所指向单元的内容与AL相乘结果存放在AX中
例:

1
2
3
4
5
6
7
MOV SI,1200H
MOV WORD PTR[SI],8765
MOV AL,[SI]
INC SI
MUL [SI]

AL*[SI]=65H*87H → AX=3543H
有符号IMUL

格式:

IMUL OPRD

执行原理:

  1. 将两个操作数取补码
  2. 做乘法运算
  3. 将乘积取补码

除法指令

也分为有符号数指令和无符号数指令,被除数必须是除数的双倍字长
无符号格式

DIV OPRD

有符号格式

IDIV OPRD

OPRD是字节数:
AX/OPRD商存入AL,余数存入AH
OPRD是双字节数:
DXAX/OPRD商存入AX,余数存入DX

逻辑运算指令

与,或,非,异或

  • 除了非运算其余都是双操作数。
  • 非运算操作数不能是立即数
  • 除了非运算指令,其余指令的执行都会影响除AF以外的标志位
  • 无论执行结果如何,CF和OF都会清零
  • 非运算不影响标志位

与指令

格式

AND OPRD1,OPRD2

操作
两操作数相“与”,结果送到目标地址
应用:

  • 实现俩操作数按位相与
  • 使目标操作数某些位清零,例:AND AL,0FH
  • 在操作数不变的情况下使CF和OF清零,例:AND AX,AX

或指令

格式

OR OPRD1,OPRD2

操作
两操作数相“或”,结果送到目标地址
应用:

  • 实现俩操作数按位相或
  • 使目标操作数个某些位变1,例:OR CL,0FH
  • 在操作数不变的情况下使CF和OF清零,例: OR AX,AX

非指令

格式

NOT OPRD

操作
操作数按位取反再送回原地址

NOT BYTE PTR[BX]

异或指令

格式

XOR OPRD1,OPRD2

操作
两操作数相“异或”,结果送到目标地址

测试指令

格式

TEST OPRD1,OPRD2

操作
执行“与”运算,但运算结果不返回目标地址
应用
常用于测试某些位的状态

移位操作指令

控制二进制位向左或向右移动的指令
在形式上为双操作,实际上为单操作数,所以当目标为存储器操作数时,需说明其字长
源操作数只能是1或者CL

  • 非循环移位指令
  • 循环移位指令

非循环移位指令

  • 逻辑左移
  • 算数左移
  • 逻辑右移
  • 算数右移

算数左移

高位移到CF,低位补0
有符号数
SAL OPRD,1
SAL OPRD,CL

逻辑左移

高位移到CF,低位补0
无符号数
SHL OPRD,1
SHL OPRD,CL

算数右移

有符号数
低位移到CF,每移动一位会将符号位复制一份放到前面
SAR OPRD,1
SAR OPRD,CL

逻辑右移

低位移到CF,高位补0
无符号数
SHR OPRD,1
SHR OPRD,CL

循环移位指令

指令格式,对操作数要求与非循环指令一样
不带进位:

  • 左移ROL
  • 右移ROR

带进位:

  • 左移RCL
  • 右移RCR

应用

  • 测试某些标志位的状态
  • 高位与低位交换
  • 可以与非循环指令一起组成更长字节数的移位

Author: ljs
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source ljs !
评论
  TOC