循环控制语句的处理及条件分支的处理方法

简介: 循环控制语句的处理及条件分支的处理方法

一、循环控制语句的处理


       上一篇博客说的都是顺序流程,现在分析一下循环流程的处理,for循环以及if条件等C语言程序的 流程控制 是如何实现的,我们还是以代码以及编译后的结果为例,看一下程序控制流程的处理过程:


// 定义MySub函数
void MySub(){
    //不做任何处理
}
// 定义MyFunc 函数
void MyFunc(){
    int i;
    for(int i = 0;i < 10;i++){
        //重复调用MySub十次
        MySub();
    }
}


上述代码将局部变量 i 作为循环条件,循环调用十次 MySub 函数,下面式它主要的汇编代码:


    xor    ebx,ebx  ; 将寄存器清0
@4  call   _MySub   ; 调用MySub函数
    inc    ebx      ; ebx寄存器的值 + 1
    cmp    ebx,10   ; 将ebx寄存器的值和10进行比较
    jl     short @4 ; 如果小于10就跳到 @4


 C 语言中的for 语句是通过在括号中指定循环计数器的初始值(i=0)、循环的继续条件(i<10)、循环计数器的更新(i++)这三种形式来进行循环处理的。与此相对的汇编代码就是通过比较指令(cmp)和跳转指令(jl)来实现的


下面我们来对上述代码进行说明


       MyFunc 函数中用到的局部变量只有i,变量i申请分配了ebx寄存器的内存空间。for 语句括号中的i=0被转换为 xor ebx,ebx 这一处理,xor指令会对左起第一个操作数和右起第二个操作数进行XOR运算,然后把结果存储在第一个操作数中。由于这里把第一个操作数和第二个操作数都指定为了ebx,因此就变成了对相同数值的XOR运算。也就是说不管当前寄存器的值是什么,最终的结果都是0.类似的,我们使用 mov ebx,0也能得到相同的结果,但是xor指令的处理速度更快,而且编译器也会启动最优化功能


XOR指的就是异或操作,它的运算规则是如果a、b两个值不相同,则异或结果为1.如果a、b两个值相同,异或结果为0


相同数值进行XOR运算,运算结果为0.XOR的运算规则是,值不同时结果为1,值相同时结果为0.例如01010101和01010101 进行运算,就会分别对各个数字位进行XOR运算。因为每个数字位都相同,所以运算结果为0


ebx 寄存器的值初始化后,会通过call 指定调用_MySub函数,从_MySub函数返回后,会执行 inc ebx指令,对ebx的值进行+1操作,这个操作就相当于i++的意思,++表示的就是当前数值+1


这里需要知道i++ 和 ++i 的区别


i++ 是先赋值,赋值完成后再对 i 执行 +1操作


++i 是先进行 +1操作,完成后再进行赋值


inc 下一行的cmp是用来对第一个操作数和第二个操作数的数值进行比较的指令。cmp ebx,10就相当于C语言中的 i<10 这一处理,意思是把ebx寄存器的值与10进行比较。汇编语言中比较指令的结果,会存储在CPU的标志寄存器中。不过,标志寄存器的值,程序是无法直接参考的。那如何判断比较结果呢?


汇编语言中有多个 跳转指令,这些跳转指令会根据标志寄存器的值来判断是否进行跳转操作,例如最后一行的jl,它会根据cmp ebx,10指令所存储在标志寄存器中的值来判断是否跳转,jl 这条指令表示的就是 jump on less than(小于的话就跳转)。发现如果 i 比10小,就会跳转到@4所在的指令处继续执行


那么汇编代码的意思也可以用C语言来改写一下,加深理解


    i ^= i;
l4: MySub();
    i++;
    if(i < 10) goto L4;


代码第一行 i^= i 指的是i和i进行异或运算,也就是XOR运算,MySub()函数用L4 标签来替代,然后进行 i 自增操作,如果 i的值小于10的话,就会一直循环 MySub()函数


二、条件分支的处理方法


条件分支的处理方式和循环的处理方式很相似,使用的也是cmp指令和跳转指令,下面用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
 {
    MySub2();
 }
}


很简单的一个实现了条件判断的C语言代码,那Borland C++ 编译的结果如下:


_MyFunc proc near
 push    ebp
 mov     ebp,esp
 mov     eax,123        ; 把123存入 eax 寄存器中
 mov     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


上面代码用到了三种跳转指令,分别是 jle(jump on less or equal)比较结果小时跳转,jge(jump on greater or equal)比较结果大时跳转,还有不管怎样都会进行跳转的jmp,在这些跳转指令之前还有用来比较的指令 cmp,构成了上述汇编代码的主要逻辑形式


目录
相关文章
|
6月前
|
C++
C++ 条件与 If 语句:掌握逻辑判断与流程控制精髓
C++ 中的条件语句用于根据布尔表达式的真假执行不同代码。`if` 用于当条件为真时执行一段代码,`else` 配合 `if` 在条件不成立时执行另一段代码。`else if` 允许测试额外的条件。`switch` 语句提供多分支选择。还有三元运算符 `(condition) ? expressionTrue : expressionFalse`,它是一种简写的 if...else 形式,常用于一行内作出决定。
91 0
|
11月前
分支和循环语句(2)补充goto语句
分支和循环语句(2)补充goto语句
53 1
|
3月前
|
Java 数据库
为什么要检查循环中的等待条件
【8月更文挑战第22天】
80 5
|
3月前
|
编译器 C语言
语句、分支与循环详解
语句、分支与循环详解
|
5月前
|
Java C++ Python
选择、条件、循环语句是编程语言中用于控制程序流程的重要语句。
选择、条件、循环语句是编程语言中用于控制程序流程的重要语句。
|
4月前
|
语音技术 数据安全/隐私保护
语音识别,猜猜心里数字讲解,猜数字的组合,判断语句的嵌套,嵌套语句使用很简单,我们写一个外层嵌套的条件,利用缩进,满足条件,才会执行条件2,判断语句综合案例,如何产生变量的随机数字,while循环应用
语音识别,猜猜心里数字讲解,猜数字的组合,判断语句的嵌套,嵌套语句使用很简单,我们写一个外层嵌套的条件,利用缩进,满足条件,才会执行条件2,判断语句综合案例,如何产生变量的随机数字,while循环应用
|
5月前
|
机器学习/深度学习
详解分支和循环结构(剖析if语句,switch语句,while循环,for循环,do-while循环)
详解分支和循环结构(剖析if语句,switch语句,while循环,for循环,do-while循环)
43 0
|
6月前
|
算法 程序员 C++
C++程序中的循环语句:实现重复执行的关键
C++程序中的循环语句:实现重复执行的关键
330 2
|
6月前
|
算法 程序员 C++
C++程序中的循环结构:控制程序重复执行的关键
C++程序中的循环结构:控制程序重复执行的关键
147 2
条件测试逻辑判断应用
条件测试逻辑判断应用
53 2