王爽 汇编语言第三版 第11章 标志寄存器

 

 

 

条件码:

  • ① OF(Overflow Flag)溢出标志,溢出时为1,否则置0.标明一个溢出了的计算,如:结构和目标不匹配.
  • ② SF(Sign Flag)符号标志,结果为负时置1,否则置0.
  • ③ ZF(Zero Flag)零标志,运算结果为0时置1,否则置0.
  • ④ CF(Carry Flag)进位标志,进位时置1,否则置0.注意:Carry标志中存放计算后最右的位.
  • ⑤ AF(Auxiliary carry Flag)辅助进位标志,记录运算时第3位(半个字节)产生的进位置。有进位时1,否则置0.
  • ⑥ PF(Parity Flag)奇偶标志.结果操作数中1的个数为偶数时置1,否则置0.

控制标志位:

  • ⑦ DF(Direction Flag)方向标志,在串处理指令中控制信息的方向。
  • ⑧ IF(Interrupt Flag)中断标志。
  • ⑨ TF(Trap Flag)陷井标志。

 

 

11.1 ZF 标志( 0 标志位 )

 

11.2 PF 标志( 奇偶 标志位

 

11.3 SF 标志 ( 结果正负标志0 表示 正,1 表示 负 )

 

https://blog.csdn.net/zhangjiuding/article/details/79133961

写出下面每条指令执行后,ZF、PF、SF等标志位的值。 

这里写图片描述

ZF标志:是否为0 
PF标志:结果中是否有偶数个为 1 的 bit位。 
SF标志:结果是否为负,仅有符号运算有用。

提示:传送指令不影响标志位。至于为什么是这样,我估计是因为更改标志位会费时间,CPU的资源很宝贵,而且转移指令的标志位并没有什么实际意义

  1. sub al,al 结果为0,有0个为1的bit位,非负。
  2. mov al,1 传送指令不影响标志位。
  3. push ax 传送指令不影响标志位。
  4. pop bx 传送指令不影响标志位。
  5. add al,bl 结果为00000010B,结果不为0,有1个为1的bit位,非负。
  6. add al,10 结果为00001100B,结果不为0,有2个为1的bit位,非负。
  7. mul al 结果为10010000B,结果不为0,有2个为1的bit位,非负。

 

 

11.4 CF 标志 ( 进位 标志位 )

 

 

11.5 OF 标志 ( 溢出 标志位 )

 

11. 6 adc 指令

 

11.7 sbb 指令

 

11.8 cmp 指令

 

 

 

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

 

 

 

 

11.10 DF 标志 和 串传送指令

 

 

11.11 pushf 和 popf

题目:下面的程序执行后,ax的值是多少?

assume cs:codesg
datasg segment
	db 16 dup(0)
datasg ends
codesg segment
    start:
    mov ax,0
    push ax
    popf
    
    mov ax,0fff0h
    add ax,0010h
    
    pushf
    pop ax
    and al,11000101b
    and ah,00001000b
    
    mov ax,4c00h
    int 21h
    
 codesg ends
 end start

这题是对第十一章标志寄存器的更好理解。
先上个图:

在这里插入图片描述

本题关键在于 OF  标志的判断。另一个关键点是 and 0000 0100 1100 0101 起到了屏蔽未学习位的作用!

一步一步来分析:

mov ax,0     将ax置0
push ax ax   入栈
popf         将栈中的数据弹出到psw(标志寄存器)中
此时 psw 中数据为:0000 0000 0000 0000b

mov ax, 0fff0h
add ax, 0010h
这两句的作用是(ax) = fff0h + 0010h,显然,psw中的数据会发生改变,问题是:如何改变呢?

CF: 假设这里是无符号运算,则1111 1111 1111 0000b(fff0h) + 0000 0000 0001 0000b(0010h) = 1 0000 0000 0000 0000b,已经发生了进位,所以CF = 1
PF: 结果保存在ax中,ax=0000h,’1’的个数是0,是偶数,所以PF标志=1

AF: AF没学,先不管,假设它是个不确定值,AF = ?
ZF: 结果是0,显然ZF = 1

SF: 结果是0,不是负数,所以SF = 1
TF: TF没学,先不管,假设它是个不确定值,AF = ?

IF: IF没学,先不管,假设它是个不确定值,AF = ?
DF: DF为方向标志位,add指令不会影响DF,前面已经将psw置0,所以DF = 0

OF: OF(溢出标志位)对初学者来说是最难的了,OF记录了有符号数运算结果是否溢出。那么,如何判断是否溢出呢?

 

假设是有符合运算,fff0h(1111 1111 1111 0000b)对应的原码是1000 0000 0001 000b(即十进制-16),这是如何算出来的?很简单:先看符号位1,说明是个负数,然后所有位取反再加1(即0000 0000
0001 0000b)得绝对值,前面确定是负数,所以符号位应该是1,则原码为1000 0000 0001 000b,同样,0010h的源码(正数的补码和原码相同)是0000 0000 0001 0000b(即十进制的16),

显然,结果是0,一个正数一个负数相加,结果肯定不会溢出!!!下面给出一个tip,用来快速判断运算是否溢出:
tip: 正加正得负,负加负得正,肯定溢出

一正一负相加肯定不会溢出

(进行正加正,负加负运算时,可以全部转为十进制来看,如果得到正加正得正,负加负得负,则需看他们结果是否在可表示范围内)

通过说明的tip,立刻可以判断出未溢出,所以OF = 0;

所以:运行完上面两条语句后,psw值为: 0000 00?? 010? 0101b

pushf 将psw的值入栈
pop ax 此时ax即: 0000 00?? 010? 0101b

and al,11000101b
and ah,00001000b

and 的是按位与,运算法则是:有0则0,我们写对齐来看

0000 00?? 010? 0101b
0000 1000 1100 0101b
显然 and 以后 ax = 0000 0000 0100 0101b = 45h

 

 

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

 

 

实验 11: 编写子程序

 

示例代码:

assume cs:codesg

datasg segment
        db "Beginner's All-purpose Symbolic Instruction Code.",0
datasg ends

codesg segment
begin:
        mov ax,datasg
        mov ds,ax
        mov si,0

        call letterc

        mov ax,4c00h
        int 21h

letterc: ;子程序部分[开始]
        push si
s0:     mov al,[si]
        cmp al,0
        je exitsub
        cmp al,61h  ; 61h为'a'的ASCII码
        jb next
        cmp al,7ah  ; 7ah为'z'的ASCII码
        ja next
        and al,11011111B    ;或使用sub al,20h
        mov [si],al
next:   inc si
        jmp short s0
exitsub:
        pop si
        ret        ;子程序部分[结束]
codesg ends
end begin



; 提示:
; 1.相当于将字符串中的每个字符在闭区间['a','z']内进行比较;
; 2.欲显示相关字符串,可调用实验10中的"显示子程序"(属第十章内容),在调用时注意相关参数的传递。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值