汇编语言(十)——条件判断指令

首先了解按位指令,这里使用的技术也可以用于操作硬件设备控制位,实现通信协议以及加密数据,

操作 说明
AND 源操作数和目的操作数进行逻辑与操作
OR 源操作数和目的操作数进行逻辑或操作
XOR 源操作数和目的操作数进行逻辑异或操作
NOT 对目标操作数进行逻辑非操作
TEST 源操作数和目的操作数进行逻辑与操作,并适当地设置 CPU 标志位

布尔指令影响零标志位、进位标志位、符号标志位、溢出标志位和奇偶标志位。下面简单回顾一下这些标志位的含义:

  • 操作结果等于 0 时,零标志位置 1。
  • 操作使得目标操作数的最高位有进位时,进位标志位置 1。
  • 符号标志位是目标操作数高位的副本,如果标志位置 1,表示是负数;标志位清 0,表示是正数。(假设 0 为正。)
  • 指令产生的结果超出了有符号目的操作数范围时,溢岀标志位置 1。
  • 指令使得目标操作数低字节中有偶数个 1 时,奇偶标志位置 1。

CMP(比较)指令执行从目的操作数中减去源操作数的隐含减法操作,并且不修改任何操作数:

CMP destination,source

当实际的减法发生时,CMP 指令按照计算结果修改溢出、符号、零、进位、辅助进位和奇偶标志位。、

 

如果比较的是两个无符号数,则零标志位和进位标志位表示的两个操作数之间的关系如右表所示:

CMP结果 ZF CF
目的操作数 < 源操作数 0 1
目的操作数 > 源操作数 0 0
目的操作数 = 源操作数 1  

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

CMP结果 标志位
目的操作数 < 源操作数 SF ≠ OF
目的操作数 > 源操作数 SF=OF
目的操作数 = 源操作数 ZF=1

置位和清除零标志位、符号标志位、进位标志位和溢出标志位有几种方法:(1)要将零标志位置 1,就把操作数与 0 进行 TEST 或 AND 操作;要将零标志位清零,就把操作数与 1 进行 OR 操作,TEST 指令不修改目的操作数,而 AND 指令则会修改目的操作数。若要符号标志位置 1,将操作数的最高位和 1 进行 OR 操作;若要清除符号标志位,则将操作数最高位和 0 进行 AND 操作。(2)若要进位标志位置 1,用 STC 指令;清除进位标志位,用 CLC 指令.若要溢出标志位置 1,就把两个正数相加使之产生负的和数;若要清除溢出标志位,则将操作数和 0 进行 OR 操作。

当状态标志条件为真时,条件跳转指令就分支到目标标号。否则,当标志位条件为假时,立即执行条件跳转后面的指令。语法如下所示:

Jcond destination

cond 是指确定一个或多个标志位状态的标志位条件。CPU 状态标志位最常见的设置方法是通过算术运算、比较和布尔运算指令。条件跳转指令评估标志位状态,利用它们来决定是否发生跳转。下面是基于进位和零标志位的例子:

JC

进位跳转(进位标志位置 1)

JNC

无进位跳转(进位标志位清零)

JZ

为零跳转(零标志位置 1)

JNZ

非零跳转(零标志位清零)

x86 指令集包含大量的条件跳转指令。它们能比较有符号和无符号整数,并根据单个 CPU 标志位的值来执行操作。条件跳转指令可以分为四个类型:

  • 基于特定标志位的值跳转
  • 基于两数是否相等,或是否等于(E)CX 的值跳转
  • 基于无符号操作数的比较跳转
  • 基于有符号操作数的比较跳转

LOOPZ(为零跳转)指令的工作和 LOOP 指令相同,只是有一个附加条件:为零控制转向目的标号,零标志位必须置 1。指令语法如下:

LOOPZ destination

LOOPE(相等跳转)指令相当于 LOOPZ 它们有相同的操作码。这两条指令执行如下任务:

ECX = ECX - 1
if ECX > 0 and ZF = 1, jump to destination

否则,不发生跳转,并将控制传递到下一条指令。LOOPZ 和 LOOPE 不影响任何状态标志位。32 位模式下,ECX 是循环计数器;64 位模式下,RCX 是循环计数器。

LOOPNZ(非零跳转)指令与 LOOPZ 相对应。当 ECX 中无符号数值大于零(减 1 操作之后)且零标志位等于零时,继续循环。指令语法如下:

LOOPNZ destination

LOOPNE(不等跳转)指令相当于 LOOPNZ 它们有相同的操作码。这两条指令执行如 下任务:

ECX = ECX - 1
if ECX > 0 and ZF = 0, jump to destination

否则,不发生跳转,并将控制传递到下一条指令。

表驱动选择是用查表来代替多路选择结构的一种方法。使用这种方法,需要新建一个表,表中包含查询值和标号或过程的偏移量,然后必须用循环来检索这个表。当有大量比较操作时,这个方法最有效。

有限状态机(FSM)是一个根据输入改变状态的机器或程序。用图表示 FSM 相当简明, 下图中的矩形(或圆形)称为节点,节点之间带箭头的线段称为边(或弧)。上图给出了一个简单的例子。每个节点代表一个程序状态,每个边代表从一个状态到另一个状态的转换。一个节点被指定为初始状态,在图中用一个输入箭头指出。其余的状态可以用数字或字母来标示。一个或多个状态可以指定为终止状态,用粗框矩形表示。终止状态表示程序无出错的结束状态。FSM 是一种被称为有向图的更一般结构的特例。

简单的有限状态机

.IF、.ELSE、.ELSEIF 和 .ENDIF 伪指令使得程序员易于对多分支逻辑进行编码。它们让汇编器在后台生成 CMP 和条件跳转指令,ELSEIF 和 .ELSE 是可选的,而 .IF 和 .ENDIF 则是必需的。

除了用 CMP 和条件跳转指令外,.REPEAT 和 .WHILE 伪指令还提供了另一种方法来编写循环。.REPEAT 伪指令执行循环体,.WHILE 伪指令显示数值 1 到 10。循环之前,计数器寄存器 (EAX) 被初始化为 0。之后,循环体内的第一条语句将 EAX 加 1。当 EAX 等于 10 时,.WHILE 伪指令将分支到循环体外。

猜你喜欢

转载自blog.csdn.net/qq_35789421/article/details/113739367