汇编笔记_第十一章

标志寄存器

标志寄存器的作用:

  • 用来存储相关指令的某些执行结果

  • 用来为CPU执行相关指令提供行为依据

  • 用来控制CPU的相关工作方式

  • 标志寄存器由16位,按位起作用,0,2,4,6,7,8,9,10,11有特殊的含义,其他的没有任何含义;

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
OF DF IF TF SF ZF AF PF CF

标志位的符号
零标志ZF(Zero flag) ZR(1) NZ(0)
奇偶标志PF(Parity flag) PE(1) PO(0)
符号标志SF(Sign flag) NG(1) PL(0)
进位标志CF(Carry flag) CY(1) NC(0)
溢出标志OF(Over flow flag) OV(1) NV(0)
方向标志DF(Direction flag) DN(1) UP(0)
中断标志IF(Interrupt flag) EI(1) DI(0)
辅助标志AF(Auxiliary carry flag) AC(1) NA(0)

零标志ZF

flag的第6位

它记录相关指令执行后,

  • 结果为0,ZF=1;
  • 结果非零,ZF=0;

例如:

mov ax,1
sub ax,1

mov ax,1
and ax,0

指令执行后,结果为0,则ZF=1;

mov ax,2
sub ax,1

mov ax,1
or ax,1

指令执行后,结果为1,则ZF=0;

在8086CPU的指令集中,有的指令的执行事影响标志寄存器的,例如:add,sub,mul,div,inc,or,and等。有的不影响,如:mov push,pop等传送指令;

奇偶标志PF

flag的第二位

它记录指令执行后,结果的所有二进制位中1的个数:

  • 为偶数,PF=1;
  • 为奇数,PF=0;

例如:

mov al,1
add al,10

执行后,PF=0;

mov al,1
or al,10

执行后,PF=1;

符号标志SF

flag的第七位

它记录指令执行后:

  • 结果为负,SF=1;
  • 结果为正,SF=0;
mov al,10000001b
add al,1

执行后SF=1;

进位标志CF

flag的第0位

在进行 无符号数运算 的时候,它记录的运算结果的最高有效位项更高位的进位值,或从更高位的借位值;

例:

mov al,98h
add al,al   ;(al)=30h,cf=1
add al,al   ;(al)=30h,cf=1

溢出标志OF

flag的第11位

在进行 有符号数运算 的时候,如果结果超出了及其所能表示的范围称为溢出;

溢出时OF=1;

注意:

  • CF是对 无符号 数运算有意义的标志位;
  • OF是对 有符号 数运算有意义的标志位;

例如:

mov al,0F0H
add al,78H

CF=1,OF=0;
对于无符号运算,0F0H+78H有进位,CF=1;对于有符号数运算,不发生溢出,OF=0;

例如:

sub al,al
;0h=0000 0000b
;CF=0    OF=0    SF=0    ZF=1    PF=1

mov al,10h
;10h=0001 0000b
;CF=0    OF=0    SF=0    ZF=1    PF=1

add al,90h
;90h=1001 0000b
;ans=1010 0000b
;CF=0   OF=0    SF=1    ZF=0    PF=1

mov al,80h
;80h=1000 0000b
;CF=0   OF=0    SF=1    ZF=0    PF=1

add al,80h
;80h=1000 0000b=128d
;ans=1 0000 0000b=256d
;CF=1   OF=1    SF=0    ZF=1    PF=1

mov al,0FCH
;0FCH=1111 1100b=252d
;CF=1   OF=1    SF=0    ZF=1    PF=1

add al,05h
;05h=0000 0101b
;ans=1 0000 0001b=257d
;CF=1   OF=0    SF=0    ZF=0    PF=0

mov al,7DH
;7DH=0111 1101b=125d
;CF=1   OF=0    SF=0    ZF=0    PF=0

add al,0BH
;0BH=0000 1011b=11d
;ans=1000 1000b=136d
;CF=0   OF=1    SF=1    ZF=0    PF=1

总结:

  • CF只看八位二进制计算后的第九位的值
  • OF看计算后的值是否在-128~127内
  • SF只看有符号数的第8位
  • ZF看8位是否都为0
  • PF看8位里的1的个数
  • 标志寄存器的改变仅在非传送指令执行时

adc指令

adc是带进位加法指令,他利用了CF位上记录的进位值;

格式:
adc 操作对象1,操作对象2

功能:
操作对象1=操作对象2+CF

例如:adc ax,bx==(ax)=(ax)+(bx)+CF

mov ax,2
mov bx,1
sub bx,ax
adc ax,1

(ax)=(ax)+1+CF=4
mov al,98h
add al,al
adc al,3

(ax)=(ax)+3+CF=30H+3+1=34H
  • adc指令和add指令相配合可以对更大的数据进行加法运算;
  • adc指令加上CF值的含义由adc之前的指令决定,如果CF是由sub设置,它的含义就是借位值,由add设置就是金为珩值;

编写一个对两个128位进制数据进行相加的子程序:

add128:
push ax
push cx
push si
push di
sub ax,ax   ;置CF为零
mov cx,8

s:
mov ax,[si]
adc ax,[si]
mov [si],ax

inc si
inc si
inc di
inc di
;注意这里只能这么写,不能改成add si,2,否则会置CF为零

loop s
pop di
pop si
pop cx
pop ax

sbb指令

sbb是带借位减法指令,利用了CF位上记录的借位值

格式:
sbb 操作对象1,操作对象2

功能:
操作对象1=操作对象1-操作对象2-CF

比如:
sbb ax,bx实现:(ax)=(ax)-(bx)-CF

sbb指令执行后,将对CF进行设置;

cmp指令

cmp是比较指令,功能相当于减法指令,但 不保存结果

cmp指令执行后,将对标志寄存器产生影响;

格式:
cmp 操作对象1,操作对象2

功能:计算操作对象1-操作对象2

不保存结果,仅仅根据计算结果对标志寄存器进行设置;

例如:

cmp ax,ax

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

cmp ax,bx 指令执行后,可以根据相关的标志位的值看出比较的结果:

如果(ax)=(bx) (ax)-(bx)=0 ZF=1
如果(ax) \(\neq\) (bx) (ax)-(bx) \(\neq\) 0 ZF=0
如果(ax) \(\lt\) (bx) (ax)-(bx)将产生借位 CF=1
如果(ax) \(\ge\) (bx) (ax)-(bx)不必借位 CF=0
如果(ax) \(\gt\) (bx) (ax)-(bx)既不必借位,结果又不为零 CF=0并且ZF=0
如果(ax) \(\le\) (bx) (ax)-(bx)既可能借位,结果可能为零 CF=1或ZF=1

cmp与add、sub一样既可以对无符号数比较也可以对有符号数比较;

不能单纯的看SF的值来判断两个操作对象的大小,因为溢出的问题;

cmp ah,bh

  • 如果SF=1,OF=0:OF=0说明没有溢出,逻辑上真正的结果的正负和实际结果的相同;SF=1,实际结果为负,所以逻辑上为负,(ah) \(\lt\) (bh);
  • 如果SF=1,OF=1:因为溢出导致实际结果为负,那么逻辑上真正结果为正,说明 (ah) \(\gt\) (bh);
  • 如果SF=0,OF=1:因为溢出导致实际结果为正,那么逻辑上真正的结果必然为负,说明 (ah) \(\lt\) (bh);
  • 如果SF=0,OF=0: (ah) \(\ge\) (bh);

条件转移指令

所有条件转移指令的转移位移是[-128,127];

通常和cmp相配合;

cmp指令的比较结果进行转移的指令分为:

  • 根据 无符号整数 的比较结果进行转移的条件转移指令,检测ZF、CF的值;
  • 根据 有符号整数 的比较结果进行转移的条件转移指令,检测SF、OF、和ZF的值;

根据无符号数的比较结果进行转移的条件转移指令:

指令 含义 检测的相关标志位
je 等于则转移 ZF=1
jne 不等于则转移 ZF=0
jb 低于则转移 CF=1
jnb 不低于则转移 CF=0
ja 高于则转移 CF=0,ZF=0
jan 不高于则转移 CF=1或ZF=1

DF标志和串传送指令

flag的第10位

功能:在串处理指令中,控制每次操作后si,di的增减;

  • DF=0:每次操作后si,di递增;
  • DF=1:每次操作后si,di递减;

格式1:movsb

功能:以字节为单位传送;

  • ((es)16+(di))=((ds)16+(si))
  • if(df==0): (si)=(si)=1,(di)=(di)+1;
  • if(df=0): (si)=(si)-1,(di)=(di)-1;

格式2: movsw

功能:以字为单位传送

rep mobsb or rep movsw

一般,movsbmovswrep 配合使用,rep的作用是根据cx的值,重复执行后面的串传送指令;

对DF位的设置:

  • cld指令:将标志寄存器的DF位置0
  • std指令:将标志寄存器的DF位置1

例如:

data segment 
    db 'Welcome to masn!'
    db 16 dup(0)
data ends
;将data段中的第一个串送到后面的空间

;传送的设置:
;传送的原始位置:ds:si
;传送的目的地址:es:di
;传送的长度:cx
;传送的方向:DF

mov ax,data
mov ds,ax
mov si,0
mov es,ax
mov di,16
mov cx,16
cld
rep movsb

pushf和popf

  • pushf: 将标志寄存器的值压栈
  • popf: 从栈中弹出数据,送入到标志寄存器中

https://www.cnblogs.com/31415926535x/p/10200283.html

(end)

posted @ 2018-12-30 18:37  31415926535x  阅读(344)  评论(0编辑  收藏  举报