7.0条件跳转
在Code部分,你可以看到像这样的标签:
.code
mov eax, edx
sub eax, ecx
cmp eax, 2
jz loc1
xor eax, eax
jmp loc2
loc1:
xor eax, eax
inc eax
loc2:
(xor eax, eax意为:eax=0)
让我们来看看这些代码:
mov eax, edx;把edx放入eax中
sub eax, ecx;eax-ecx
cmp eax, 2
这有一条新指令:cmp。Cmp意为compare(比较)。它能比较两个值(寄存器,内存,直接数值)并设置Z-flag(零标志)。零标志很像carry,也是内部标志寄存器的一位。
Jz loc1
这也是条新的。它是条件跳转指令。Jz=jump if zero(如果设置了零标志就跳转)。Loc1是一个标记指令“xor eax,eax|inc eax”内存开始处offset的标签。因而jz loc1=如果设置了零标志,跳往位于loc1的指令。
Cmp eax, 2;如果eax=2设置零标志
Jz loc1;如果设置了零标志就跳转
=如果eax等于2,跳往位于loc1的指令
然后有jmp loc2.这也好似一个跳转,但是是一个无条件跳转:它总是执行。上面的代码就是:
if ((edx-ecx)==2)
{
eax = 1;
}
else
{
eax = 0;
}
或者Basic版:
IF (edx-ecx)=2 THEN
EAX = 1
ELSE
EAX = 0
END IF
3. 1标志寄存器
标志寄存器有一套标志。它们设不设置取决于计算或其他时间。我不会讨论它们的全部。只拣几个重要的说:
ZF(零标志)
当计算结构是零时该标志被设置(compare实际上是只设置标志不保存结构的减法)
SF(符号标志)
结构为负就设置
CF(carry标志)
Carry标志中有计算后最右的位。
OF(溢出标志)
标明一个溢出了的计算。如,结构和目标不匹配。
还有更多的标志(Parity, Auxiliary, Trap, Interrupt, Direction, IOPL, Nested Task, Resume, & Virtual Mode)但因为我们不用它们,所以我不解释。
7.2跳转系列
有一整套的条件跳转,而且它们跳转与否均取决于标志的状态。但由于大部分跳转指令有明白的名字,你甚至无需知道哪个标志要设置,例如:“如果大于等于就跳转”(jge)和“符号标志=溢出标志”一样,而“如果零就跳转”和“如果零标志=1就跳转”一样。
在下表中,“意思”指的是什么样的计算结果该跳转。“如果大于就跳转”意为:
cmp x, y
jmp 如果 x 比 y大
伪代码
意思
条件
JA
Jump if above
CF=0 & ZF=0
JAE
Jump if above or equal
CF=0
JB
Jump if below
CF=1
JBE
Jump if below or equal
CF=1 or ZF=1
JC
Jump if carry
CF=1
JCXZ
Jump if CX=0
register CX=0
JE (is the same as JZ)
Jump if equal
ZF=1
JG
Jump if greater (signed)
ZF=0 & SF=OF
JGE
Jump if greater or equal (signed)
SF=OF
JL
Jump if less (signed)
SF != OF
JLE
Jump if less or equal (signed)
ZF=1 or SF!=OF
JMP
Unconditional Jump
-
JNA
Jump if not above
CF=1 or ZF=1
JNAE
Jump if not above or equal
CF=1
JNB
Jump if not below
CF=0
JNBE
Jump if not below or equal
CF=1 & ZF=0
JNC
Jump if not carry
CF=0
JNE
Jump if not equal
ZF=0
JNG
Jump if not greater (signed)
ZF=1 or SF!=OF
JNGE
Jump if not greater or equal (signed)
SF!=OF
JNL
Jump if not less (signed)
SF=OF
JNLE
Jump if not less or equal (signed)
ZF=0 & SF=OF
JNO
Jump if not overflow (signed)
OF=0
JNP
Jump if no parity
PF=0
JNS
Jump if not signed (signed)
SF=0
JNZ
Jump if not zero
ZF=0
JO
Jump if overflow (signed)
OF=1
JP
Jump if parity
PF=1
JPE
Jump if parity even
PF=1
JPO
Jump if paity odd
PF=0
JS
Jump if signed (signed)
SF=1
JZ
Jump if zero
ZF=1
所有的跳转指令需要一个参数:要跳往的offset。