下面让我们来看一下条件分支的实现方法。条件分支的实现方法同循环处理的实现方法类似,使用的也是cmp指令和跳转指令,这一点估计大家也预料到了。
没错,条件分支就是利用这些指令来实现的。不过,为了以防万一,我们来确认一下。代码清单10-11是,根据变量a的值来调用不同函数(MySub1函数、MySub2函数、MySub3函数)的C语言源代码。为了实现条件分支,这里使用了if语句。示例中被调用的各个函数,都不进行任何处理。将代码清单10-11的MyFunc函数处理转换成汇编语言源代码后,结果就如代码清单10-12所示。
代码清单10-11 进行条件分支的C语言源代码
//定义MySub1函数voidMySub1() {//不做任何处理 }//定义MySub2函数voidMySub2() {//不做任何处理 }//定义MySub3函数voidMySub3() {//不做任何处理 }//定义MyFunc函数voidMyFunc() {inta=123;//根据条件调用不同的函数if (a>100) {MySub1(); }elseif (a<50) {MySub2(); }else {MySub3(); } }
代码清单10-12 将代码清单10-11的MyFunc函数转换成汇编语言后的结果
_MyFuncprocnearpushebp;movebp, esp;moveax,123;把123存入eax寄存器中cmpeax,100;把eax寄存器的值同100进行比较jleshort@8;等于或小于100时,跳转到@8标签call_MySub1;调用MySub1函数jmpshort@11;跳转到@11标签@8: cmpeax,50;把eax寄存器的值同50进行比较jgeshort@10;大于等于50时,跳转到@10标签call_MySub2;调用MySub2函数jmpshort@11;跳转到@11标签@10: call_MySub3;调用MySub3函数@11: popebpret_MyFuncendp
代码清单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语句,大家没有必要这么紧张。