8086cpu中的标志寄存器与比较指令

在8086CPU中有一个特殊的寄存器——标志寄存器,该寄存器不同于其他寄存器,普通寄存器是用来存放数据的读取整个寄存器具有一定的含义,但是标志寄存器是每一位都有固定的含义,记录在运算中产生的信息,标志寄存器的机构如下图:

寄存器中的第1、3、5、 12、 13、 14 、15位在8086CPU中没有使用,其他位置代表不同的含义,各个位置的意思如下(该表截自百度知百科中的标志寄存器):

一般我们常用到的是如下几个标志

1)CF:CF标志表示进位,我们知道对于8086CPU来说,寄存器只能存储16位二进制数,但是有些指令产生的结果可能大于16位,比如:

mov ax,200h
add ax, 0fffffh

产生的结果已经超过16位,由于ax寄存器只能保存16位数据,因此高位产生的数据必然被丢弃,但是也不是简单的丢弃,这个时候CF标志位会变成1,表示结果产生了进位;

2)PF:表示标志,这个奇偶不是数字本身是奇数或者是偶数,表示的是某个数据中有奇数个1或者是偶数个1;

3)ZF:0标志:表示计算结果是否为0;

4)SF:符号标志记录相关计算结束后得到的结果是否为负,若为负则标志位为1,否则标志位为0;

5)方向标志:方向标志用于内存单元的拷贝,我们在将一段内存单元拷贝到另一段内存中去时使用循环一个字节一个字节的拷贝,但是8086CPU提供了一个指令movsb 、movsw分别是按字节拷贝和按字拷贝,这两个指令所对应的源内存地址只能用

ds:[si],目的地址只能用es:[di]表示,其中DF标志指明我们是从低到高字节拷贝还是从高到低字节拷贝,当df = 1时,地址递减, = 0时地址递增;

6)OF:溢出标志,它的作用与CF相同,当得到的操作数大于16位的时候,该标志置为1,但是OF用于有符号数,而CF用于无符号数。

7)IF:在DEBUG中使用,当我们启动DEBUG模式的时候,一条指令执行完后,该寄存器被置为1,这个时候会调用相应的中断程序,使我们的代码在该位置停止执行,以便我们查看相应的结果; CMP指令

CNP指令使用的格式为CMP 操作数1,操作数2;

cmp指令的作用是将两个操作数相减,并根据结果改变标志寄存器的值,但是并不保存计算结果,当两个数都为正时,如果ZF = 0则说明两个数相等,这个指令一般用于判断两个数据的大小关系,如果我们只是使用它,那么在判断两个数字的大小关系上,可能还会判断其他内容,假设我们使用了cmp n1, n2这样的指令的话,那么可能出现三种情况:

1)n1 = n2:要判断是不是出现这种情况只需要判断ZF是否为0,当ZF为0时两数相等;

2)n1 >n2:我们知道大数减去小数结果一定为正,是不是只需要判断SF呢?不是!在数学上大数减去小数结果一定为正这是肯定的,但是在计算机中确并不一定是这样的,我们需要考虑到是否溢出的问题比如“ffffh - (-2)”这个结果在数学上肯定是负数,但是在计算机上结果却为正,,这个时候除了要校验SF还需要校验OF,当溢出产生的时候结果正好与我们使用SF校验的相反;

3)n1 < n2:这个结果的校验与上述的校验类似;

然而幸运的是,在我们实际比较两个数据大小的时候我们并不需要这样,80886CPU为我们提供了一系列指令用来做这个工作:

指令 含义 检测的相关标志位

je:(jmp equal) 当两数相等时跳转;ZF = 1

jne(jmp not equal): 当两数不相等的时候跳转;ZF = 0

jb(jmp blow); 小于时跳转;CF = 1

jnb(jmp not blow) 不小于时跳转;CF = 0

ja(jmp above) 大于时跳转;CF= 0且ZF = 0

jna(jmp not above) 不大于时跳转;CF = 1或ZF = 0

以上指令指示检测标志寄存器中相应位置的值来判断,至于在它的前面是否使用了cmp指令CPU并不关心,在执行这些指令的时候只要CPU检测到相关的标志满足条件则会自动跳转,比如执行下面的指令:

mov ax,0
add ax,ax
je s1
inc ax
s1:
   inc ax

CPU执行到je的时候检测到ZF寄存器为0,这个时候会自动跳转到s1处的代码中执行,不会执行je的下一行代码。为了实现比较功能最好将cmp与这些指令配套使用。高级语言中的if语句正是用着一套指令实现的

一般在破解时可能需要修改某些标识,以达到跳转或者不跳转的目的,下面是我从小甲鱼网站上找到的图片,记录了各个跳转指令实现所需要的条件,根据这个表中的内容,修改相应标识,就可以控制程序执行流程

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏听雨堂

NumPY学习笔记

对于被多年数据库应用锻炼成“二维表”思路的人来说,NumPY的ndarray实在是太好用了! 1、创建数组 可以用np.array(python数组),np....

1888
来自专栏张戈的专栏

Linux:sed命令详解

1. 简介 sed 是非交互式的编辑器。它不会修改文件,除非使用 shell 重定向来保存结果。默认情况下,所有的输出行都被打印到屏幕上。 ? sed 编辑器逐...

4736
来自专栏云霄雨霁

Java虚拟机--内存模型

2235
来自专栏calmound

ZOJ 2724 Windows Message Queue(优先队列)

优先队列的概念及使用方法 题意:输入GET,队列为空则输出空,否则输出最优先的数据(所谓最优先,就是优先值最小的一个),若输入PUT,输入三个数据,分别是名字,...

3675
来自专栏cloudskyme

什么是线程安全

什么是线程安全?       如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且...

3238
来自专栏加米谷大数据

MongoDB 概念解析

不管我们学习什么数据库都应该学习其中的基础概念,在mongodb中基本的概念是文档、集合、数据库,下面我们挨个介绍 下表将帮助您更容易理解Mongo中的一些概念...

35411
来自专栏hbbliyong

C#新功能--命名参数与可选参数

  可能是篇幅太短了,又被打入冷宫了.先重发一篇加上可选参数.本来不想加这个呢,因为可选参数可能大家用的会多点.其实这 两个在VB中早就有了,C#中,在.net...

3345
来自专栏kevindroid

java多线程——线程的状态

1703
来自专栏程序员互动联盟

【答疑释惑】标准C语言如何操作文件?

C语言中操作文件功能都用ANSI C提供的一组标准库函数来实现。文件操作标准库函数有如下: fprintf:往文件中写格式化数据 fscanf:格式化读取文件中...

3819
来自专栏Java面试笔试题

什么是ORM?

对象关系映射(Object-Relational Mapping,简称ORM)是一种为了解决程序的面向对象模型与数据库的关系模型互不匹配问题的技术;简单的说,O...

1542

扫码关注云+社区

领取腾讯云代金券