image.png

标志位

ZF 标志

add``sub``mul``div``inc``or``and的运算结果为0,则zf=1反之zf=0

PF 标志

运算结果的1的个数是偶数,则pf=1,是奇数,则pf=0

01也是偶数

  1. mov al,1
  2. add al,10; al=00001011B pf=3

SF 标志

计算机的二进制通常使用补码表示,即无符号129的补码为10000001B,这也是有符号-127的补码
因此129+1=130(10000010B)``-127+1=-126(10000010B)都是正确的
sf用于记录结果是否为,是负则sf=1,当我们需要数据是有符号的时候,sf就有意义,不需要的时候就没有意义

CF 标志

无符号运算,进位标志位,记录最高有效位的借位、进位情况

无符号运算,只有正数

  1. mov al,98H
  2. add al,al ; 10011000B(98h)+10011000B(98h)=(1)00110000B(130h) 向高位进位 1, cf=1
  3. ; 结果 al=30h
  1. mov al,97H
  2. sub al,98H ; 10010111B-10011000B=(1)10010111B-10011000B=11111111B(ffH) 向高位借位, cf=1
  3. ; 也等于加上 98H 的补码

cfadd1,则表示进位,被sub1,则表示借位

OF 标志

有符号运算,溢出标志位

  1. mov al,62H ; 十进制 98
  2. add al,63H ; 十进制 99
  3. ; 结果 c5H, 即无符号十进制 197(正确结果), 有符号的 -59 的补码(错误结果), 此时发生溢出, of=1
  1. mov al,0f0H ; -16 的补码
  2. add al,088H ; -120 的补码
  3. ; 结果 78H, 有符号 120 的补码(错误结果)

DF 标志

df=0每次操作后si``di增加
df=1每次操作后si``di减小

指令

adc 指令

带进位的加法,adc ax,1等价于(ax)+1+cf,有利于进行更高位数的加法

  1. ; 计算 1EF000H + 201000H
  2. mov ax,001EH ; 保存高位
  3. mov bx,F000H ; 保存低位
  4. add bx,1000H ; 16位相加
  5. adc ax,0020H ; 16位相加, 并加上低位的进位

128 位数相加

  1. add128:push ax
  2. push cx
  3. push si
  4. push di
  5. sub ax,ax ; cf 0
  6. mov cx,8 ; 循环 8 次(128位有8个字,16个字节)
  7. s:mov ax,[si] ; 128位数据由低→高排, 循环取出
  8. adc ax,[di]
  9. mov [si],ax ; 结果保存在 [si]
  10. inc si ; 不能使用 add si,2 因为会改变 cf
  11. inc si
  12. inc di
  13. inc di
  14. loop s
  15. pop di
  16. pop si
  17. pop cx
  18. pop ax
  19. ret

sbb 指令

带借位的减法,sbb ax,1等价于ax-1-cf

  1. ; 计算 003E1000H - 00202000H
  2. mov bx,1000H
  3. mov ax,003EH
  4. sub bx,2000H
  5. sbb ax,0020H

cmp 指令

进行sub操作,但不进行保存

cmp ax,bx仅进行ax-bx从而改变cf``of``sf``zf``pf,但不会把结果保存在ax

无符号

  1. zf=1(ax)=(bx)
  2. zf=0(ax)≠(bx)
  3. cf=1(ax)<(bx)
  4. cf=0(ax)≥(bx)
  5. cf=0zf=0(ax)>(bx)
  6. cf=1zf=1(ax)≤(bx)

    有符号

  7. sf=1``of=0(ax)<(bx)

  8. sf=1``of=1(ax)>(bx)
  9. sf=0``of=0(ax)≥(bx)
  10. sf=0``of=1(ax)<(bx)

    检测结果条件转移

    无符号

    | je | 相等跳转 | zf=1 | | —- | —- | —- | | jne | 不相等跳转 | zf=0 | | jb | 小于跳转 | cf=1 | | jnb | 不小于跳转 | cf=0 | | ja | 大于跳转 | cf=0zf=0 | | jna | 不大于跳转 | cf=1zf=1 |
  1. start:cmp ah,bh
  2. je s
  3. add ah,bh
  4. s:add ah,ah
  5. ; ah=bh, ah=ah+ah, 否则 ah=ah+bh

注意检测的是标志位,而不是相不相等,即mov ax,0``add ax,0zf=1也会跳转

串传送

movsb

相当于((es)×16+(di))=((ds)×16+(si))并且根据df进行di``si的增减1个字节

  1. rep movsb

上面代码等价于

  1. s:movsb
  2. loop s

movsw

movsb类似,不过di``si增减2个字节(即1个字)

cld

df设置成0

  1. ; 将字符串复制到另一个字符串中
  2. assume cs:code,ds:data
  3. data segment
  4. db 'welcome to masm!'
  5. db 16 dup (0)
  6. data ends
  7. code segment
  8. mov ax,data
  9. mov ds,ax
  10. mov si,0 ; ds:si=data:0
  11. mov es,ax
  12. mov di,16 ; es:di=data:0010
  13. mov cx,16
  14. cld
  15. rep movsb
  16. code ends
  17. end

std

df设置成1

pushf/popf

将标志寄存器入栈和出栈

  1. assume cs:code
  2. code segment
  3. start:mov ax,0
  4. push ax
  5. popf ; flag=0000h
  6. mov ax,0fff0h
  7. add ax,0010h ; ax=(1)0000h
  8. pushf ; flag=0047h
  9. pop ax ; ax=0047
  10. and al,11000101B ; al=45h
  11. and ah,00001000B ; ah=00h
  12. mov ax,4c00h
  13. int 21h
  14. code ends
  15. end start

debug 中的表示

image.png


1 0
OF OV NV
SF NG PL
ZF ZR NZ
PF PE PO
CF CY NC
DF DN UP