算术运算

符号扩展

符号扩展:用一个操作数的符号位(即最高位)形成另一个操作数
结果:后一个操作数各位是0(正数)或者是1(负数)
符号扩展不改变数据大小

将字节转换成字指令

语句格式:

CBW(convert byte to word)

功能: 将AL中的符号扩展至AH中, 操作数是隐含且固定的

将字转换成双字指令

语句格式:

CWD

功能: 将AX中的符号扩展至DX中, 操作数是隐含且固定的

比较指令CMP

格式:CMP OPD,OPS
功能:(OPD) — (OPS)
说明:目的操作数减去源操作数,然后根据结果设置标志位,但该结果并不存入目的地址
影响标志位: AF、CF、OF、PF、SF 、 ZF
作用: 一般的后面跟一条条件转移指令,根据比较结果转向不同的程序分支,用于处理OPDOPS大小比较的不同情况

逻辑运算

逻辑与

AND
指令的格式

AND Reg/Mem, Reg/Mem/Imm

受影响的标志位
CF(0)、OF(0)、PF、SF和ZF(AF无定义)

逻辑或

OR
指令的格式

OR Reg/Mem, Reg/Mem/Imm

受影响的标志位
CF(0)、OF(0)、PF、SF和ZF(AF无定义)

逻辑非

NOT
指令的格式

NOT Reg/Mem

受影响的标志位:无

异或

XOR
指令的格式

XOR Reg/Mem, Reg/Mem/Imm

受影响的标志位
CF(0)、OF(0)、PF、SF和ZF(AF无定义)

TEST

格式

TEST  Reg/Mem, Reg/Mem/Imm

作用
执行AND,但是不影响目标操作数
受影响的标志位
CF(0)、OF(0)、PF、SF和ZF(AF无定义)。

Eg: test  ax, ax  
    // ax 为0,  则ZF = 0
    // ax 不为0,则ZF = 1

技巧

  1. 如果要将目的操作数中某些位清0,用AND,称之为屏蔽
  2. 如果要将目的操作数中某些位置1,用OR
  3. 用来测试目的操作数中某一位或某几位是否为0或1,而目的操作数不变,TEST,
  4. TEST与CMP的区别,前者是测试一位或几位,后者测试整个字节/字/双字是否相等
  5. 操作数自身相或、相与结果不变。
  6. XOR AX,AX 将AX置0,比mov ax,0 更高效。

算术运算指令

加减乘除

加法

  1. add加法 可能产生溢出
  2. 相关的标志位是 CF
  3. adc加法会计算当前CF

add

ADD reg,imm/reg/mem
    ;reg←reg+imm/reg/mem
ADD mem,imm/reg
    ;mem←mem+imm/reg

adc

ADC reg,imm/reg/mem
    ;reg←reg+imm/reg/mem+CF
ADC mem,imm/reg
    ;mem←mem+imm/reg+CF

inc

inc: 加一,不影响CF标志位

inc ax

大数运算

编写汇编指令计算加法:
  $7654 3218 + fa23 fbc3 = 1 7078 2DDB$

赋值:
mov ax,3218
mov bx,7654
运算:
add ax,fbc3//加法
adc bx,fa23//加法,考虑进位

结果:

CF     [bx]        [ax]  
1    7078        2DDB  

减法

  1. sub减法 可能产生借位
  2. 相关的标志位是 CF
  3. sbb减法会计算当前CF

sub

SUB reg,imm/reg/mem
    ;reg←reg-imm/reg/mem
SUB mem,imm/reg
    ;mem←mem-imm/reg

sbb

SBB reg,imm/reg/mem
        ;reg←(reg-(imm/reg/mem)-CF)
SBB mem,imm/reg    
        ;mem←mem-imm/reg-CF

dec

dec: -1,不影响CF位

dec ax

大数运算

 $7078 2DDB- 7654 3218= FA23 FBC3$

赋值:
mov ax,2DDB
mov bx,7078

运算:
sub ax,3218
sbb bx,7654

结果:

CF     [bx]        [ax]  
1    FA23        FBC3  

乘法

无符号乘法

格式:MUL Reg/Mem
功能:显式操作数*隐含操作数(看成无符号数)
影响标志位:CF和OF

位数隐含的被乘数乘积的存放位置举例
8ALAXMUL BL
16AXDX-AXMUL BX
32EAXEDX-EAXMUL ECX

无符号乘法影响标志位

  • 如果乘积的高一半位(AH/DX/EDX) 包含有乘积的有效位
    CF=1、OF=1
    否则 CF=0,OF=0

OF=CF=1则说明:

  • 字节*字节结果超过了8位
  • 字*字节结果超过了16位
  • 双字*双字结果超过了32位

有符号乘法

格式:

IMUL Reg/Mem 
IMUL Reg, Imm ;80286+ 
IMUL Reg, Reg, Imm ;80286+ 
IMUL Reg, Reg/Mem ;80386+ 

功能: 有符号数相乘
影响标志位: CF和OF

有符号乘法影响标志位

  • 如果乘积的高一半位(AH,DX,EDX)不是低位的符号扩展
    则CF=1、OF=1
    否则,CF=0,OF=0

举例:

al = 03H, bl = 40H$
imul bl

除法

无符号除法

格式:

DIV  Reg/Mem
位数被除数被除数除数余数
8AX8 bit opsALAH
16DX,AX16 bit opsAXDX
32EDX,EAX32 bit opsEAXEDX

影响标志位:未定义
未定义:指令执行后这些标志是任意的,不可预测的
没有影响:指令执行后不改变标志状态

有符号除法

格式:

IDIV  Reg/Mem
位数被除数被除数除数余数
8AX8 bit opsALAH
16DX,AX16 bit opsAXDX
32EDX,EAX32 bit opsEAXEDX

影响标志位:AF、CF、OF、PF、SF和ZF

除法溢出

  • 被除数远大于除数时,所得的商就有可能超出它所能表达的范围
  • idiv除法溢出
    字节除时商不在-128~127范围内,或者在字除时商不在-32768~32767范围内
  • div除法溢出
    8位除法运算结果大于8位,16位除法运算结果大于16位
    举例:

    ax = FFFF
    bl = FF
    div bl

    结果:
    相当于FFFF / FF = 101
    此时AH显然放不下,所以商溢出了

求补指令 NEG

  1. NEG指令对操作数执行求补运算: 用零减去操作数,然后结果返回操作数
  2. 求补运算也可以表达成: 将操作数按位取反后加1
  3. neg ax ;如果ax = 0,则CF标志位 = 0;若ax != 0, 则CF = 1
neg ax

三目运算 无分支

求通解:
Reg == a ? b : b-1

要求: 
不使用分支实现 运算
我们把操作数 给ax

Reg == 0 ? 0 : -1
解:
mov ax, 3
neg ax //不为0就会影响CF
sbb ax,ax //ax=ax-ax-CF

Reg == 6 ? 0 : -1
解:
mov ax,3 //给测试值
sub ax,6
neg ax  
sbb ax,ax
add ax,0

Reg == 6 ? 9 : 8
解:
mov ax,3 
sub ax,6
neg ax  
sbb ax,ax
add ax,9

Reg == a ? b : b-1
解:
mov ax,3 
sub ax,a
neg ax  
sbb ax,ax
add ax,b
求通解:
Reg == a ? b-1 : b

要求: 
不使用分支实现 运算
我们把操作数 给ax

Reg == 0 ? -1 :0 
解:
mov ax,3
neg ax 
mov ax,0
adc ax,-1

Reg == a ? -1 : 0
解:
mov ax,3 
sub ax,a
neg ax 
mov ax,0
adc ax,-1

Reg == 6 ? 8 : 9
解:
mov ax,3 
sub ax,6
neg ax 
mov ax,0
adc ax,-1
add ax,9

Reg == a ? b-1 : b
解:
mov ax,3 
sub ax,a
neg ax 
mov ax,0
adc ax,-1
add ax,b
求通解:
Reg == a ? b : c
Reg == 8 ? 3 : 13

mov ax,9
sub ax,a
neg ax
sbb ax,ax
and ax,c-b
add ax,b
Last modification:December 17, 2018
如果觉得我的文章对你有用,请随意赞赏