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

CSDN话题挑战赛第2期
参赛话题:学习笔记

目录

一、循环控制语句的处理

二、条件分支的处理方法


一、循环控制语句的处理

        上一篇博客说的都是顺序流程,现在分析一下循环流程的处理,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

扫描二维码关注公众号,回复: 14560050 查看本文章

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,构成了上述汇编代码的主要逻辑形式

猜你喜欢

转载自blog.csdn.net/m0_61961937/article/details/127192094
今日推荐