下面让我们来看一下条件分支的实现方法。条件分支的实现方法同循环处理的实现方法类似,使用的也是cmp指令和跳转指令,这一点估计大家也预料到了。
没错,条件分支就是利用这些指令来实现的。不过,为了以防万一,我们来确认一下。代码清单10-11是,根据变量a的值来调用不同函数(MySub1函数、MySub2函数、MySub3函数)的C语言源代码。为了实现条件分支,这里使用了if语句。示例中被调用的各个函数,都不进行任何处理。将代码清单10-11的MyFunc函数处理转换成汇编语言源代码后,结果就如代码清单10-12所示。
代码清单10-11 进行条件分支的C语言源代码
//定义MySub1函数
void MySub1()
{
//不做任何处理
}
//定义MySub2函数
void MySub2()
{
//不做任何处理
}
//定义MySub3函数
void MySub3()
{
//不做任何处理
}
//定义MyFunc函数
void MyFunc()
{
int a =123;
//根据条件调用不同的函数
if (a > 100)
{
MySub1();
}
else if (a < 50)
{
MySub2();
}
else
{
MySub3();
}
}
代码清单10-12 将代码清单10-11的MyFunc函数转换成汇编语言后的结果
_MyFunc proc near
push ebp;
mov ebp, esp;
mov eax,123 ;把123存入eax寄存器中
cmp eax,100 ;把eax寄存器的值同100进行比较
jle short @8 ;等于或小于100时,跳转到@8标签
call _MySub1 ;调用MySub1函数
jmp short @11 ;跳转到@11标签
@8: cmp eax,50 ;把eax寄存器的值同50进行比较
jge short @10 ;大于等于50时,跳转到@10标签
call _MySub2 ;调用MySub2函数
jmp short @11 ;跳转到@11标签
@10: call _MySub3 ;调用MySub3函数
@11: pop ebp
ret
_MyFunc endp
代码清单10-12中用到了三种跳转指令,分别是比较结果小或相等时跳转的jle(jump on less or equal)、大或相等时跳转的jge(jump on greater or equal)、不管结果怎样都无条件跳转的jmp。在这些跳转指令之前还有用来比较的cmp指令,比较结果被保存在了标志寄存器中。这里我们添加了注释,大家不妨顺着程序的流程看一下。虽然同C语言源代码的处理流程不完全相同,不过大家应该知道处理结果是相同的。此外,还有一点需要注意的是,eax寄存器表示的是变量a。
虽然大部分的C语言参考书中都写着“为了便于理解程序的结构,应尽量避免使用无条件分支的goto语句”,不过,在汇编语言这一领域中,如果不使用相当于C语言goto语句的jmp指令,就无法实现循环和条件分支。由此看来,关于应不应该在C语言中使用goto语句,大家没有必要这么紧张。