条件处理

本章要点

1.简介

2.布尔和比较指令

3.条件跳转

4.条件循环指令

5.条件结构

6.应用:有限状态机

7.决策伪指令

6.1  简介

本章,读者将看到高级条件分支如何翻译成底层的实现代码。

处理硬件设备的程序必须能够操控数字中的单个数据位,应该能够测试清楚和设置数据位。数据加密和压缩也依赖于位操作。

本章试图解答如下基本问题:

1.如何使用1章中介绍的布尔运算符(AND,OR和NOT)?

2.在汇编语言中如何写一条IF语句?

3.编译器是如何将嵌套的IF语句翻译成机器语言的?

4.如何设置和清楚二进制数字中的单个位?

5.在布尔表达式中有符号和无符号树有什么区别?

6.什么是有限状态机?

7.GOTO语句真是有害的吗?

本章遵循自底向上的姿势,首先讲述程序逻辑背后的二进制基础知识,接下来讲述如何使用CPU指令和处理器状态标识来比较操作数,最后将所有这些进行综合讲述如何使用汇编语言实现高级语言的逻辑结构。

6.2  布尔和比较指令

下面开始在二进制层次学习如何进行条件处理,使用布尔代数中的4种基本操作-AND,OR,XOR和NOT,这类操作在计算机硬件和软件设计中都有广泛的应用。

IA-32指令集中包括AND,OR,XOR,NOT,TEST和BTop指令,直接实现了字节、字和双字的布尔运算。

6.2.1  CPU的状态标志

布尔指令影响零标志、进位标志、符号标志、溢出标志和奇偶标志。

1.零标志操作的结果等于0时置位。

2.进位标志在指令执行产生的结果(视为无符号整数)对目的操作数而言太大(或太小)而无法容纳时的置位。

3.符号标志是目的操作数高位的一份副本,如果目的操作数为负数则设置该标志,如果是正数则清零。

4.溢出标志在指令产生的有符号结果无效时置位。

5.在指令的操作数的低字节中,为1的数据位的数据量偶数时设置奇偶标志。

6.2.2 AND指令

AND指令在每对操作数的对应数据位之间执行布尔(位)“与”操作并把结果放在目的操作数中

AND 目的操作数,源操作数,下面的操作数格式都是允许的:

AND reg ,reg

AND reg ,mem

AND reg ,imm

AND mem,reg

ANDmem,imm

6.2.3  OR指令

格式和AND一样......

影响的标志位:OR指令总是清除溢出标志和进位标志。它根据目的操作数的值修改符号标志、零标志、奇偶标志。可以把一个数字同自身进行“或”运算以获取关于其值的某些信息,如:

or al,al

零标志和符号标志的值与AL中的内容关系如下:

6.2.4 XOR指令

XOR指令在每对操作数的对应数据之间执行布尔“异或”操作,格式个AND一样。

影响的标志:XOR指令总是清楚溢出标志和进位标志,它依据目的操作数的值修改零标志和奇偶标志。

检查奇偶标志:奇偶标志位表明了位做操作或幻速运算结果的最低字节包含为1的数据的个数是奇数还是偶数。当为1的数据位为欧舒适设置奇偶标志,为奇数时清除该标志。检验数字中为1的数据位个数的奇偶性的方法之一是将数字同全0字节进行异或运算,无需改变其值:

6.2.5  NOT指令

NOT指令对于一个操作数所有数据位取反,得到的结果成为该操作数的反码。该指令允许下面的操作数据类型:

NOT  reg

NOT  mem

影响的标志:NOT指令不影响任何状态标志。

6.2.6  TEST指令

TEST指令在没对操作数的对应数据位之间执行隐含的“与”操作,并相应设置标志位。TEST指令和AND指令之间的唯一区别在于TEST指令饼不修改目的操作数。TEST指令的操作数格式与AND相同,该指令在测试操作数某些为是否被设置时特别有用。

6.2.7  CMP指令

CMP指令在源操作数和目的操作数之间执行隐含的减法操作,两个操作数都不会被修改:

CMP  目的操作数,源操作数

CMP指令与AND指令的操作数格式相同。

    影响的标志:CMP指令根据对目的操作数进行假象的减法操作后目的操作数的值修改溢出标志、符号标志、零标志、进位标志、辅助进位标志和奇偶变址的值。在比较两个无符号操作数的时候,零标志和进位标志反应了两个操作数之间的关系:

如果比较的两个操作数是有符号的,则符号标志、零标志、溢出标志与两个操作数之间的关系如下表所示:

CMP指令时创建条件逻辑结构的有效工具。IF语句在汇编语言中等价于在CMP指令后

跟一条条件跳转指令。

例子:下面我们来看三个代码片段,以弄清CMP指令时如何影响标志的。在AX中装入5并且和10进行比较的时候,由于5-10需要借位,因此CF标志置位:

mov ax,5

cmp ax,10

比较1000和1000会设置零标志位,因为从源数中减去目的数得到的结果是0:

比较105和0会清楚零标志和进位标志,因为105大于0:

6.2.8  设置和清除单个CPU状态标志

如何设置和清除零标志、符号标志、进位标志和溢出标志?有很多种方法,但大多数方法都需要修改目的操作数。要设置零标志,可以讲操作数同0进行TEST或AND操作;要想清除零标志,可以将操作数同1进行OR操作:

test   al ,0    ;设置零标志

and   al ,0    ;设置零标志

or    al ,1    ;清楚零标志

TEST指令不会修改操作数,不过AND操作修改操作数。要设置符号标志,将操作数的最高位同1进行OR操作;要清楚该标志,将操作数的高位同0进行AND操作:

or  al ,80h  ;设置符号标志

and al ,7Fh  ;清楚符号标志

使用STC指令可以设置进位标志,使用CLC指令可以清除进位标志:

stc    ;设置进位标志

clc    ;清楚进位标志

要设置溢出标志,把两个将得到复数和的整数字节相加;要清楚溢出标志,将操作数同0进行OR操作:

mov  al ,7Fh  ;al = +127

inc   al      ;al =80h(-128) ,OF = 1

or    eax ,0  ;清除溢出标志

Intel汇编语言程序设计学习-第六章 条件处理-上的更多相关文章

  1. Intel汇编语言程序设计学习-第六章 条件处理-中

    6.3  条件跳转 6.3.1  条件结构 在IA-32指令集中没有高级的逻辑结构,但无论多么复杂的结构,都可以使用比较和跳转指令组合来实现.执行条件语句包括两个步骤:首先,使用CMP,AND,SUB ...

  2. Intel汇编语言程序设计学习-第六章 条件处理-下

    6.6  应用:有限状态机 这个东西说了半天,感觉就是把逻辑弄得跟有向图一样,没看出来什么高端的东西,下面就整理下书上说的概念: 有限状态机(FSM,Finite-State Machine)是依据输 ...

  3. Intel汇编语言程序设计学习-第五章 过程-上

    过程 5.1  简介 需要阅读本章的理由可能很多: 1.读者可能想要学习如何在汇编语言中进行输入输出. 2.应该了解运行时栈(runtime stack),运行时栈是子过程(函数)调用以及从子过程返回 ...

  4. Intel汇编语言程序设计学习-第四章 数据传送、寻址和算术运算-下

    4.3  和数据相关的操作符和伪指令 操作符和伪指令并非机器可执行的指令,相反,它们是由汇编器进行解释的.开发者可以使用一系列的MASM操作符或伪指令获取数据的地址以及大小等特征信息: OFFSET操 ...

  5. Intel汇编语言程序设计学习-第五章 过程-下

    5.3.3  库测试程序 测试程序#1:整数I/O 该测试程序把输出文本的颜色改为蓝底黄字,然后以十六进制数显示七个数组的内容,最后提示用户输入一个有符号整数,再分别以十进制.十六进制和二进制格式重复 ...

  6. Intel汇编语言程序设计学习-第三章 汇编语言基础-下

    3.4  定义数据 3.4.1  内部数据类型 MASM定义了多种内部数据类型,每种数据类型都描述了该模型的变量和表达式的取值集合.数据类型的基本特征是以数据位的数目量的大小:8,16,32,,48, ...

  7. Intel汇编语言程序设计学习-第三章 汇编语言基础-中

    3.2  例子:整数相加减 现在来看一个进行整数加减操作的汇编语言小程序.寄存器用于存放中间数据,我们调用一个库函数在屏幕上显示寄存器的内容.下面是程序的源码: TITLE Add and Subtr ...

  8. Intel汇编语言程序设计学习-第三章 汇编语言基础-上

    汇编语言基础 3.1  汇编语言的基本元素 有人说汇编难,有人说汇编简单,我个人不做评价,下面是一个简单的实例(部分代码): main PROC mov  eax,5  ;5送EAX寄存器 add   ...

  9. Intel汇编语言程序设计学习-第一章 基本概念

    第一章基本概念 1.1  简单介绍 本书着重讲述MS-Windows平台上IA-32(Intel Architecture 32bit,英特尔32位体系架构)兼容微处理器的汇编语言程序设计,可以使用I ...

随机推荐

  1. 如何在 ASP.Net Core 中使用 Lamar

    ASP.Net Core 自带了一个极简的 开箱即用 的依赖注入容器,实际上,你还可以使用第三方的 依赖注入容器 来替代它,依赖注入是一种设计模式,它能够有效的实现对象之间的解耦并有利于提高单元测试和 ...

  2. Python装饰器(2)

    上一篇介绍了装饰器的常规使用方法,即函数形式的装饰器.这篇文章中,进一步介绍类class跟装饰器的相关知识. [用装饰器来装饰类函数] 这是今天介绍的第一种使用场景,比较常见.因为目前好多的编程语言都 ...

  3. string与bson.ObjectId之间格式转换

    string转bson.ObjectId bson.ObjectIdHex(string) bson.ObjectId转string日后再补

  4. DEV表格设置列不可编辑

    现在是可编辑的 Run Designer--Columns--Column options下的AllowEdit属性改为false即可

  5. 根据数据渲染DOM树形菜单——中途感想

    根据数据渲染DOM树形菜单,这个需求做了几天了.一开始觉得用while也可以实现一层一层查找数据,但后来发现while还是做不到,因为我查找这个动作必须有进入有出来然后进入下一个条目,但while只能 ...

  6. 翻译 - ASP.NET Core 基本知识 - 配置(Configuration)

    翻译自 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-5.0 ASP ...

  7. Jaeger Client Go 链路追踪|入门详解

    目录 从何说起 Jaeger 部署 Jaeger 从示例了解 Jaeger Client Go 了解 trace.span tracer 配置 Sampler 配置 Reporter 配置 分布式系统 ...

  8. 关于在forEach中使用await的问题

    先说需求,根据数组中的ID值,对每个ID发送请求,获取数据进行操作. 首先肯定考虑用forEach 或者 map对数组进行遍历,然后根据值进行操作,但是请求是个异步操作,forEach又是一个同步操作 ...

  9. Macbook 安装kali linux 双系统 2020.3 超详细

    博主折腾了一星期这东西,到现在都还有些坑没解决(最后面会讲).不过最起码系统装上了,可以用了,看到这桌面惊艳了,再点下左上角表示人间值得. 其实我是装了windos 10.macos 和kali三系统 ...

  10. Scrapy框架的安装

    Win+R 输入cmd打开命令行 我们先把pip升级到最新版,输入代码如下: pip install --upgrade pip 不过一般这种更新方式会经常性出错,安装文件在下载到一半时就会超时报错 ...