汇编语⾔(⼗)——条件判断指令
⾸先了解按位指令,这⾥使⽤的技术也可以⽤于操作硬件设备控制位,实现通信协议以及加密数据,
操作说明
AND源操作数和⽬的操作数进⾏逻辑与操作
OR源操作数和⽬的操作数进⾏逻辑或操作
XOR源操作数和⽬的操作数进⾏逻辑异或操作
NOT对⽬标操作数进⾏逻辑⾮操作
TEST源操作数和⽬的操作数进⾏逻辑与操作,并适当地设置 CPU 标志位
布尔指令影响零标志位、进位标志位、符号标志位、溢出标志位和奇偶标志位。下⾯简单回顾⼀下这些标志位的含义:
操作结果等于 0 时,零标志位置 1。
操作使得⽬标操作数的最⾼位有进位时,进位标志位置 1。
符号标志位是⽬标操作数⾼位的副本,如果标志位置 1,表⽰是负数;标志位清 0,表⽰是正数。(假设 0 为正。)
指令产⽣的结果超出了有符号⽬的操作数范围时,溢岀标志位置 1。
指令使得⽬标操作数低字节中有偶数个 1 时,奇偶标志位置 1。
CMP(⽐较)指令执⾏从⽬的操作数中减去源操作数的隐含减法操作,并且不修改任何操作数:
CMP destination,source
当实际的减法发⽣时,CMP 指令按照计算结果修改溢出、符号、零、进位、辅助进位和奇偶标志位。、
如果⽐较的是两个⽆符号数,则零标志位和进位标志位表⽰的两个操作数之间的关系如右表所⽰:
CMP结果ZF CF
⽬的操作数 < 源操作数01
⽬的操作数 > 源操作数00
⽬的操作数 = 源操作数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 伪指令将分⽀到循环体外。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论