汇编语言(十一)--标志寄存器

第十一章 标志寄存器

8086CPU的标志寄存器有16位,其中存储的信息通常被称为程序状态字(PSW)
我们己经使用过8086CPU的ax、bx、cx、dx、si、di、bp、sp、ip、cs、ss、ds、es等13个寄存器了。
本章中的标志寄存器(以下简称为flag)是我们要学习的最后一个寄存器。

而flag寄存器是按位起作用的,也就是说,它的每一位都有专门的含义,记录特定的信息

11.1 ZF标志

flag的第6位是ZF,零标志位。它记录相关指令执行后,

结果为0 ,ZF = 1
结果不为0,ZF = 0

对于ZF的值,我们可以这样来看,ZF标记相关指令的计算结果是否为0,如果为0,则在ZF要记录下“是0”这样的肯定信息。
在计算机中1 表示逻辑真,表示肯定,所以当结果为0的时候 ZF=1,表示“结果是0 ”。如果结果不为0,则ZF要记录下“不是0”这样的否定信息。
在计算机中0表示逻辑假,表示否定,所以当结果不为0 的时候ZF=0,表示“结果不是0”。

注意:

在8086CPU的指令集中,有的指令的执行是影响标志寄存器的,比如:add、sub、mul、div、inc、or、and等,它们大都是运算指令(进行逻辑或算术运算);
有的指令的执行对标志寄存器没有影响,比如:mov、push、pop等,它们大都是传送指令。

11.2 PF标志

flag的第2位是PF,奇偶标志位。
它记录指令执行后,结果的所有二进制位中1的个数:

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

11.3 SF标志

flag的第7位是SF,符号标志位。它记录指令执行后,
结果为负,SF = 1;
结果为正,SF = 0。
有符号数与补码
示例
mov al,10000001B
add al,1

结果: (al)=10000010B

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

这也就是说,CPU在执行 add 等指令时,是必然要影响到SF标志位的值的。

11.4 CF标志

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

比如,两个8 位数据:98H+98H,将产生进位。
由于这个进位值在8位数中无法保存,我们在前面的课程中,就只是简单地说这个进位值丢失了。

其实CPU在运算的时候,并不丢弃这个进位值,而是记录在一个特殊的寄存器的CF位上。

而当两个数据做减法的时候,有可能向更高位借位。
比如,两个 8 位数据:97H-98H,将产生借位,借位后,相当于计算197H-98H。
而flag的CF位也可以用来记录这个借位值。

11.5 OF标志

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

一般情况下,OF记录了有符号数运算的结果是否发生了溢出。

如果发生溢出,OF=1,
如果没有,OF=0。

一定要注意CF和OF的区别:
CF是对无符号数运算有意义的标志位;
而OF是对有符号数运算有意义的标志位。

对于无符号数运算,CPU用CF位来记录是否产生了进位
对于有符号数运算,CPU 用 OF 位来记录是否产生了溢出
当然,还要用SF位来记录结果的符号,而CF与OF之间没有任何关系

11.6 abc指令

adc是带进位加法指令 ,它利用了CF位上记录的进位值。
格式: adc 操作对象1,操作对象2
功能: 操作对象1=操作对象1+操作对象2+CF
比如:adc ax,bx 实现的功能是:(ax)=(ax)+(bx)+CF

在执行 adc 指令的时候加上的 CF 的值的含义,由 adc指令前面的指令决定的,也就是说,关键在于所加上的CF值是被什么指令设置的。
显然,如果CF 的值是被sub指令设置的,那么它的含义就是借位值;如果是被add指令设置的,那么它的含义就是进位值

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

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

11.7 sbb指令

sbb是带错位减法指令,它利用了CF位上记录的借位值。
格式:sbb 操作对象1,操作对象2
功能:操作对象1=操作对象1–操作对象2–CF
比如:sbb ax,bx
实现功能: (ax) = (ax) – (bx) – CF

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

11.8 cmp指令

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

cmp指令
格式:cmp 操作对象1,操作对象2
功能:计算操作对象1–操作对象2 但并不保存结果,仅仅根据计算结果对标志寄存器进行设置。

只运用cmp与SF指令,在单纯地考察SF 的值不可能知道结果的正负。因为SF 记录的只是可以在计算机中存放的相应位数的结果的正负,此时可能发生溢出

因此,我们应该在考察SF(得知实际结果的正负)的同时考察OF(得知有没有溢出),就可以得知逻辑上真正结果的正负,同时就可以知道比较的结果。

(1)如果SF=1,而OF=0
OF=0,说明没有溢出,逻辑上真正结果的正负=实际结果的正负;
因SF=1,实际结果为负,所以逻辑上真正的结果为负,所以(ah)<(bh)。

(2)如果SF=1,而OF=1
OF=1 ,说明有溢出,逻辑上真正结果的正负≠实际结果的正负;
因 SF=1 ,实际结果为负,实际结果为负,而又有溢出,这说明是由于溢出导致了实际结果为负,
简单分析一下,就可以看出,如果因为溢出导致了实际结果为负,那么逻辑上真正的结果必然为正。这样,SF=1,OF = 1 ,说明了(ah)>(bh)。

(3)如果SF=0,而OF=1
OF=1 ,说明有溢出,逻辑上真正结果的正负≠实际结果的正负;
因SF=0,实际结果非负,而OF=1说明有溢出,则结果非 0 ,所以,实际结果为正。实际结果为正,而又有溢出,这说明是由于溢出导致了实际结果非负,
简单分析一下,就可以看出,如果因为溢出导致了实际结果为正,那么逻辑上真正的结果必然为负。这样,SF=0,OF = 1 ,说明了(ah)<(bh)。

(4)如果SF=0,而OF=0

OF=0,说明没有溢出,逻辑上真正结果的正负=实际结果的正负;
因SF=0,实际结果非负,所以逻辑上真正的结果必然非负。所以(ah)≥(bh)。

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

“转移”指的是它能够修改IP,而“条件”指的是它可以根据某种条件 ,决定是否修改IP。
比如:jcxz就是一个条件转移指令,它可以检测 cx 中的数值,如果(cx)=0,就修改IP,否则什么也不做。
所有条件转移指令的转移位移都是[-128,127]。

除了 jcxz 之外,CPU还提供了其他条件转移指令,大多数条件转移指令都检测标志寄存器的相关标志位,根据检测的结果来决定是否修改IP。

它们检测的是哪些标志位呢?
就是被cmp指令影响的那些,表示比较结果的标志位。

因为 cmp 指令可以同时进行两种比较,无符号数比较和有符号数比较,所以根据 cmp 指令的比较结果进行转移的指令也分为两种,即:

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

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

编程:统计data段中数值为8的字节的个数,用ax保存统计结果。

编程思路:初始设置(ax)=0,然后用循环依次比较每个字节的值,找到一个和8相等的数就将ax的值加1。

        mov ax,data
        mov ds,ax
        mov bx,0       ;ds:bx指向第一个字节
        mov ax,0       ;初始化累加器
        mov cx,0
     s: cmp byte ptr [bx],8  ;和8进行比较
         jne next        ;如果不相等转到next,继续循环
         inc ax           ;如果相等就将计数值加1
 next: inc bx
         loop s           ;程序执行后: (ax)=3

        mov ax,data
        mov ds,ax
        mov bx,0          ;ds:bx指向第一个字节
        mov ax,0          ;初始化累加器
        mov cx,0
     s: cmp byte ptr [bx],8  ;和8进行比较
         je ok               ;如果相等就转到ok,继续循环
         jmp short next ;如果不相等就转到next,继续循环
    ok: inc ax             ;如果相等就将计数值加1
 next: inc bx
         loop s

比起第一个程序,它直接的遵循了“等于8则计数值加1”的原则,用je指令检测等于8的情况,但是没有第一个程序精简。
第一个程序用 jne 检测不等于 8 的情况 ,从而间接地检测等于 8 的情况。

11.10 DF标志和串传送指令

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

11.10.1 格式1: movsb

功能:(以字节为单位传送)
(1) ((es)×16 + (di)) = ((ds) ×16 + (si))
(2) 如果DF = 0则: (si) = (si) + 1;(di) = (di) + 1
如果DF = 0则:(si) = (si) - 1;(di) = (di) - 1

我们可以用汇编语法描述movsb的功能如下:mov es:[di],byte ptr ds:[si];8086 并不支持这样的指令,这里只是个描述。
如果DF=0:inc si,inc di
如果DF=1:dec si ,dec di

可以看出,movsb 的功能是将 ds:si 指向的内存单元中的字节送入 es:di中,然后根据标志寄存器DF位的值,将 si和di递增或递减。

11.10.2格式2:movsw

功能:(以为单位传送)
将 ds:si指向的内存字单元中word送入es:di中,然后根据标志寄存器DF位的值,将si和di递增2或递减2。

我们可以用汇编语法描述movsw的功能如下:mov es:[di],word ptr ds:[si];8086 并不支持这样的指令,这里只是个描述。
如果DF=0:add si,2; add di,2
如果DF=1:sub si,2; sub di,2

movsb和movsw进行的是串传送操作中的一个步骤,一般来说,movsb 和 movsw 都和rep配合使用,格式如下:
rep movsb 用汇编语法来描述rep movsb的功能就是: s : movsb loop s
rep movsw用汇编语法来描述rep movsw的功能就是: s : movsw loop s

可见,rep的作用是根据cx的值,重复执行后面的串传送指令。
由于每执行一次movsb指令si和di都会递增或递减指向后一个单元或前个单元,则rep movsb就可以循环实现(cx)个字符的传送

flag的DF位决定着串传送指令执行后,si和di改变的方向

8086CPU提供下而两条指令对DF位进行设置:
cld指令:将标志寄存器的DF位置0
std指令:将标志寄存器的DF位置1

编程:用串传送指令,将data段中的第一个字符串复制到它后面的空间中。
data segment
db ‘Welcome to masm!’
db 16 dup (0)
data ends
我们分析一下,使用串传送指令进行数据的传送,需要给它提供一些必要的信息,它们是:
① 传送的原始位置:ds:si;
② 传送的目的位置:es:di;
③ 传送的长度:cx;
④ 传送的方向:DF。

在这个问题中,这些信息如下:
① 传送的原始位置:data:0;
② 传送的目的位置:data:16;
③ 传送的长度:16;
④ 传送的方向: 因为正向传送(每次串传送指令执行后,si和di 递增)比较方便,所以设置DF=0。

程序:

 mov ax,data
 mov ds,ax
 mov si,0       ;ds:si指向data:0
 mov es,ax
 mov di,16     ;es:di指向data:16
 mov cx ,16   ;(cx)=16,rep循环16次
 cld               ;设置DF=0,正向传送
 rep movsb

11.11 pushf和popf

pushf :将标志寄存器的值压栈;

popf :从栈中弹出数据,送入标志寄存器中。

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

11.12 标志寄存器在Debug中的表示

在Debug中,标志寄存器是按照有意义的各个标志位单独表示的。

下面列出Debug对我们已知的标志位的表示:

标志值为1的标记值为0的标记
OFOVNV
SFNGPL
ZFZRNZ
PFPEPO
CFCYNC
DFDNUP
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值