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。