汇编语言学习第十一章-标志寄存器

本博文系列参考自<<汇编语言>>第三版,作者:王爽

8086CPU的标志寄存器有16位,其中存储的信息通常被称为程序状态字(PSW)。除了前面介绍的寄存器。本博文将介绍最后一个寄存器,标志寄存器。不同于之前的寄存器,标志寄存器是按位起作用的。其每一位都有特殊的含义。

8086标志寄存器的结构如下图所示:

标志寄存器的1,3,5,12,13,14,15都没有特殊含义。其0,2,4,6,7,8,9,10,11用作标志位使用。

11.1 ZF标志(zeros flag)

标志寄存器第6位为ZF标志寄存器,代表零标志,该标志位记录相关指令执行结束后是否为0。如果结果为0,那么zf=1,如果结果不为0,那么zf=0.

比如:

mov ax,1
sub  ax,1

sub指令执行结束后结果为0,所以ZF=1

再比如:

mov ax,2
sub   ax,1

sub指令执行结束后结果不为0,所以ZF=0

11.2  PF标志

标志寄存器的第二位为PF,该标志位为奇偶标志位,其记录相关指令执行结束后结果值的二进制位中1的个数是否为偶数,如果1的个数为偶数,则PF=1。如果1的个数为奇数,则PF=0.

比如:

mov al,1
add  al,10

执行后,结果为00001011B,其中又三个1,则PF=0

再比如:

mov al,1
or   al,2

执行结果为:00000011B,其中又两个1,为偶数,则PF=1

11.3  SF标志

标志位的第七位为SF,为符号标志位,执行完相关指令后,如果为负,则SF=1.如果为正,则SF=0

计算机可以将我们进行相关运算的数据看成有符号数和无符号数。比如:

mov al,10000001B
add  al,1

运算结束之后(al)=10000010B

当我们将ADD指令的运算看做无符号数的运算的时候(al)=130,如果我们将ADD指令的运算看做有符号数的运算的时候(al)=-126

所以,当我们把相关指令的运算数据看成有符号数的运算的时候,标志位SF的符号改变才会有意义,当我们把相关指令的运算数据看成无符号数的运算的时候。这时候虽然SF位有可能会改变,但是此时SF位的改变将无意义。

11.4  CF标志

标志寄存器的第0位为CF位,CF为记录的是无符号数运算的时候运算结果的最高位向更高位的进位结果,或从更高位的借位值。

假设对于8位的无符号数的更高位的理解如下图:

例如当两个数相加的时候,可能会产生向最高位的进位,然而这个位是不能保存下来的,其实并非直接舍弃,而是改变进位标识符CF的值。比如两个8位的数据98H+97H会产生向更高位的进位。

比如:

mov al,98h
add al,al  执行后 al=30h,cf=1
add al,al  执行后 al=60h,cf=0

再比如,当两个数相减的时候,可能会产生想最高位借位的信息:

mov al,97h
sub  al,98h  执行后(al)=FFH ,cf=1
sub  al,al      执行后(al)=0 , cf=0

11.5 OF标志

OF标志位溢出位标志,在第11位,标号在对有符号数进行运算的时候,如果超过机器能够表示的有符号数的范围,我们称为溢出。

比如8位有符号范围为-128~127 16位有符号数范围为-32768-32767

举例:

mov al,98h
add  al,97h

执行结果为197,超过了8位有符号数的正上限127。

再比如:

<pre name="code" class="plain"><pre name="code" class="plain">mov al,0F0H  F0H为有符号数-16的补码
add al,088H   88H为有符号数-120的补码


执行结果为-136,超过了8位有符号数的负下线-128

如果在进行有符号数运算的时候发生溢出,结果将不正确。

比如

mov al,98h
add  al,97h

add指令的结果为(al)=0C5H,因为是有符号数的运算,所以al中存储的是有符号数,而C5H的为右符号数为-59的补码,98+99=-59显然是不正确的。造成这钟错误的原因是8位寄存器放不下197

再比如

mov al,0F0H  F0H为有符号数-16的补码
add al,088H   88H为有符号数-120的补码

add运算后(al)=78H,因为进行的是有符号数的运算,所以al存储的是有符号数,而78h代表的有符号数120,则-16-120=120这样显然不正确。还是那个原因,因为8位有符号数的范围存储不下-136

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

比如:

mov al,98h
add  al,97h

运算后CF=0,OF=1,因为add运算后的值为197,对于8位无符号数的运算,没有产生进位,所以CF=0.对于8位有符号数的运算,已经超过上限127,所以OF=1

再比如:

mov al,0F0H  F0H为有符号数-16的补码
add al,088H   88H为有符号数-120的补码

运算后CF=1,OF=0,因为对于8位无符号数来言,add运算后的值为178H(376)超过了无符号8位数的上限产生进位,CF=1.对于8位有符号数来言,add运算后的值为-136未超过8位无符号数的下限。所以未产生溢出。OF=0;

我们可以看出CF与OF所表示的进位和溢出,是分别针对无符号数和右符号数的运算而言的。它们之间无任何关系。

11.6  adc指令

adc是带进位的加法,利用CF标志位

指令格式:adc  对象1,对象2

指令意义:对象1=对象1+对象2+CF

比如 adc ax,bx 的含义是(ax)=(ax)+(bx)+CF

指令 add ax,bx

相当于

add al,bl

adc ah,bh

11.7  sbb指令

sbb是带借位的减法,利用CF标志位

指令格式:sbb 对象1,对象2

指令含义:对象1=对象1-对象2-CF

比如sbb ax,bx的含义是(ax)=(ax)-(bx)-CF

11.8  cmp指令

cmp相当于减法指令,但是cmp不保存减法结果,只是对相关的寄存器影响

指令格式;cmp 对象1,对象2

比如 cmp ax,ax

做ax-ax运算结果为0,并不保存结果,仅影响flag标志位,执行指令后:zf=1,pf=1,sf=0,cf=0,of=0

比如cmp ax,bx通过查看标志位可以对ax和bx比较大小,比较过程如下:

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

转移是指改变IP的值,条件则是根据满足某种条件再更改IP值,进而实现跳转。

常见的比较跳转指令如下:

理解一个跳转指令的意义可以遵循如下规律:

11.10  DF标志和串传送指令

标志寄存器的第十位为DF标志位,方向标志位。在串处理指令中,控制每次操作后SI,DI的增减。

df=0 每次操作后si,di递增

df=1 每次操作后si,di递减

串操作指令:

指令格式: movsb

解释如下:

((es)*16+(di))=((ds)*16+si)

如果df=0  (si)=(si)+1  (di)=(di)+1

如果df=1  (si)=(si)-1  (di)=(di)-1

可以看出Movsb是将es:si指向的内存单元的字节送入es:di中,根据df值,设置si,di递增或者递减。

类似的指令还有movsw,Movsw是将es:si指向的内存单元的字送入es:di中,根据df值,设置si,di递增或者递减。

通畅将rep与movsb或者movsw配合使用:rep movsb 其含义是将:

s:movsb

loop s

所以rep movsb可以实现循环(cx)次的字节复制或者传送。

11.11  pushf和popf

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

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

在debug工具中用r命令可以看到由下角有一些奇怪的符号,其实这些符号就是标志寄存器在debug下的表示。其对应关系如下图所示:

时间: 2024-11-05 18:47:06

汇编语言学习第十一章-标志寄存器的相关文章

汇编语言(王爽) 第11章 标志寄存器

这里讲一个特殊的寄存器,flag 先看flag的16位显示 11.1 zf 指令执行后,结果0,ZF=1 指令执行后,结果不为0,ZF=0 11.2 pf 指令执行后,所有bit位中1的个数是否位偶数,若为偶数,那么pf=1 若为奇数,pf=0 11.3 sf 指令执行后,结果负,SF=1 指令执行后,结果不为负,SF=0 11.4 cf 进位 若出现进位,那么CF=1 没有的话CF=0 11.5 of 溢出, 数字的溢出. 8位范围是-128-127 若130就是溢出了 11.6 abc指令

汇编语言学习第四章-第一个程序

本博文系列参考自<<汇编语言>>第三版,作者:王爽 前面的几章中我们断断续续的学习了一些指令,但是从来没有完整的通过汇编语言编写一个可执行文件即.exe文件.从本章开始我们将开始使用汇编语言并通过编译器编译链接一个完整的可执行文件. 4.1 一个源程序从写出到执行的过程 如下图所示,为一个完整的汇编程序到执行的过程: 上图的过程可以总结成以下几个步骤: (1) 根据汇编语言语法规则和目标程序工程编写汇编程序.这一步在文本编辑器或者在一些IDE中编写. (2) 通过汇编编译器将编写的

汇编语言学习第六章-包含多个段的程序

本博文系列参考自<<汇编语言>>第三版,作者:王爽 在前面的介绍的程序中只有一个代码段.那么如果我们需要将代码,数据分别存储在不同的内存空间应该怎么办呢?我们知道我们不可能随便使用任何一段内存空间,因为我们这段内存地址空间可能存储着非常重要的内容.其实,这只是我们考虑的太多啦,一旦我们将程序载入内存后,操作系统为我们分配的用于程序运行的内存空间都是安全的,绝对不会与其他程序的内存空间相重叠的. 往往程序获取内存有两种方式:一种是在程序载入内存的时候操作系统已经分配好的内存空间,另外

汇编语言学习第七章-更灵活的定位内存地址的方法

本博文系列参考自<<汇编语言>>第三版,作者:王爽 前面已经通过类似[0]和[bx]的方法进行了内存定位了.本章将涉及更多内存地址定位和编程的方法. 7.1 and 和 or 指令 (1) and指令,逻辑按位与指令 例如: mov al,01100011B and al,00111011B 执行后 al=00100011B and指令可以用来将某个数的位置为零. 比如我们要将al的第二位置为零,则: and al,11111101B 依次类推. (2) or指令,逻辑按位或指令

汇编语言学习第五章-[BX]和loop指令

本博文系列参考自<<汇编语言>>第三版,作者:王爽 1.[bx]和内存单元的描述 [bx]与我们前面见过的[0]类似,mov ax,[0] 的意思是将内存地址为DS:0的两字节内容存入ax中.其中[0]中的0代表的是偏移地址. 类似的,我们有 mov al,[0]的意思是将内存地址为DS:0的单字节内容存入al中.那么我们可以大胆的推断mov ax,[bx]代表的是将偏移地址为bx寄存器中的值的内存地址的两字节内容存入到ax中,其段地址在DS中存储. 2.关于定义的描述性符号: &

汇编入门学习笔记 (十)—— 标志寄存器

疯狂的暑假学习之  汇编入门学习笔记 (十)--  标志寄存器 参考: <汇编语言> 王爽 第11章 CPU内部有一种特殊的寄存器叫标志寄存器(flag),它与ax,bx,cx等其他寄存器不同,它不是用来存放数据的,而是用来存放状态的.flag寄存器是按位器作用的,即只有0和1. flag寄存器的结构: 15     14    13    12     11     10     9     8     7     6     5     4     3     2     1     0

标志寄存器(学习汇编)

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 NT IOPL OF DF IF TF SF ZF AF PF CF 未使用 嵌套标志 I/O权限标志占2位 溢出标志 方向标志 中断允许标志 单步标志 符号标志 零标志 未使用 辅助标志 未使用 奇偶标志 未使用 进位标志 1.CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理机,个数和结构都有可能不同)具有以下3种作用. (1)用来存储相关指令的某些执行结果: (2)用来为CPU执行相关指令提供行为依据: (3

【WPF学习】第三十一章 WPF命令模型

原文:[WPF学习]第三十一章 WPF命令模型 WPF命令模型由许多可变的部分组成.总之,它们都具有如下4个重要元素: 命令:命令表示应用程序任务,并且跟踪任务是否能够被执行.然而,命令实际上不包含执行应用程序任务的代码. 命令绑定:每个命令绑定针对用户界面的具体区域,将命令连接到相关的应用程序逻辑.这种分解的设计是非常重要的,因为单个命令可用于应用程序中的多个地方,并且在每个地方具有不同的意义.为处理这一问题,需要将同一命令与不同的命令绑定. 命令源:命令源触发命令.例如,MenuItem和B

o&#39;Reill的SVG精髓(第二版)学习笔记——第十一章

第十一章:滤镜 11.1滤镜的工作原理 当SVG阅读器程序处理一个图形对象时,它会将对象呈现在位图输出设备上:在某一时刻,阅读器程序会把对象的描述信息转换为一组对应的像素,然后呈现在输出设备上.例如我们用SVG的<filter>元素指定一组操作(也称作基元,primitive),在对象的旁边显示一个模糊的投影,然后把这个滤镜附加给一个对象: <fliter id="drop-shadow"> <!-- 这是滤镜操作 --> </fliter&g