汇编语言学习笔记——第十一章 标志寄存器

CPU内部的寄存器中,有一种特殊的寄存器具有以下3中作用:
– 用来存储相关指令的某些执行结果
– 用来为CPU执行的相关指令提供行为依据
– 用来控制CPU的相关工作方式

8086CPU的标志寄存器(以下简称flag)有16位,其中存储的信息通常被称为程序状态字(PSW)。flag和其他寄存器不一样,其他寄存器都是整个寄存器具有一个含义。而flag寄存器是按位起作用的,每一位有专门的含义,记录特定的信息

ZF标志

flag的第6位是ZF,零标志位。它记录相关指令执行后,其结果是否为0。如果结果为0,那么zf=1;结果不为0,zf=0。

mov ax,1
sub ax,1
执行后,结果为0,则zf=1

影响标志寄存器的指令大都是运算指令(进行逻辑或算术运算);没有影响的大都是传送指令。

PF标志

flag的第2位是PF,奇偶标志位。它记录相关指令执行后,其结果的所有bit位中1的个数是否为偶数。若是,pf=1,如果为奇数,那么pf=0

mov al,1        ;0001H
add al,10       ;1010H

执行后,结果为00001011B,其中有3个1,则pf=0

SF标志

flag的第7位是SF,符号标志位。它记录相关指令执行后,其结果是否为负。如果结果为负,sf=1;结果非负,sf=0。

SF标志是CPU对有符号数运算结果的一种记录,它记录数据的正负。在我们将数据当作有符号数来运算的时候,可以通过它来得知结果的正负。如果我们将数据当作无符号数来运算,SF的值就没意义,虽然相关的指令影响了它的值。

mov al,10000001B
add al,1

执行后,结果为10000010B,sf=1,表示:如果指令进行的是有符号运算,那么结果为负。

CF标志

flag的第0位是CF,进位标志位。一般情况下,在进行无符号运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。

当两个数相加的时候,有可能产生从最高有效位向更高有效位的进位。CPU在运算的时候,并不丢弃这个进位值,而是记录在CF位上。

mov al,98H
add al,al

执行后:(al) = 30H,CF = 1,CF记录了从最高有效位向更高有效位的进位值

mov al,97H
sub al,98H

执行后,(al) = FFH,CF = 1,CF记录了向更高位的借位值

OF标志

flag的第11位是OF,溢出标志位。OF记录了有符号运算的结果是否发生了溢出。如果发生了溢出,OF = 1,没有发生溢出,OF = 0。

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

CF和OF的区别:CF是对无符号数运算有意义的标志位,而OF是对有符号数运算有意义的标志位。

mov al,98       ;01100010B
add al,99       ;01100011B

指令执行后,CF=0,OF=1
对于无符号数运算,98+99没有进位,CF=0
对于有符号数运算,98+99发生溢出,OF=1

adc指令

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

指令格式:adc ax,bx
功能:(ax) = (ax) + (bx) + CF

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

下面的指令和add ax,bx具有相同的结果:

add al,bl
adc ah,bh

CPU提供adc指令的目的,就是用来进行加法的第二步运算的。adc指令和add指令相配合就可以对更大的数据进行加法运算。

sbb指令

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

指令格式:sbb ax,bx
功能:(ax) = (ax) - (bx) - CF

计算003E1000H - 00202000H
mov bx,1000H
mov ax,003EH
sub bx,2000H
sbb ax,0020H

cmp指令

cmp是比较指令,其功能相当于减法指令,但是不保存结果。cmp指令执行后,对标志寄存器产生影响。 其他指令通过识别这些被影响的标志寄存器位来得知比较结果。

指令格式:cmp ax,ax
功能:(ax) - (ax)

结果为0,但并不在ax中保存,仅影响flag的相关位。
指令执行后:zf=1,pf=1,sf=0,cf=0,of=0

检测比较结果的条件转移指令

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

下面是常用的根据无符号数的比较结果进行转移的条件转移指令

–指令––含义––检测的相关标志位–
je等于则转移zf=1
jne不等于才转移zf=0
jb低于则转移cf=1
jnb不低于则转移cf=0
ja高于才转移cf=0且zf=0
jna不高于才转移cf=1或zf=1

实现如下功能:
如果(ah)=(bh)则(ah) = (ah)+(ah),否则(ah)=(ah)+(bh)

    cmp ah,bh
    je s
    add ah,bh
    jmp short ok
s:  add ah,ah
ok: :

DF标志和串传送指令

flag的第10位是DF,方向标志位。
在串处理指令中,控制每次操作后si、di的增减。
– df=0 每次操作后si、di递增
– df=1 每次操作后si、di递减

串传送指令

movsb

格式:movsb

功能:将ds:si指向的内存单元中的字节送入es:di中,
执行movsb指令相当于进行下面的几步操作

1. ((es)*16+(di)) = ((di)*16+(si))
2. 如果df=0则:
        (si)=(si)+1
        (di)=(di)+1
    如果df=1则:
        (si)=(si)-1
        (di)=(di)-1

movsw

格式:movsw

功能:将ds:si指向的内存单元中的送入es:di中,
执行movsb指令相当于进行下面的几步操作

rep

一般来说,movsb和movsw都和热捧配合使用,格式如下:

rep movsb

用汇编语法来描述就是:

s:  movsb
    loop s

可见,rep 的作用是根据cx的值,重复执行后面的串传送指令。

对df位进行设置

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

pushf和popf

pushf的功能是将标志寄存器的值压栈,popf是从栈中弹出数据,送入标志寄存器中。

为直接访问标志寄存器提供了一种方法。