循环控制语句的处理及条件分支的处理方法 待我称王封你为后i 2024-04-03 09:54 15阅读 0赞 [CSDN话题挑战赛第2期][CSDN_2] 参赛话题:[学习笔记][Link 1] **目录** 一、循环控制语句的处理 二、条件分支的处理方法 -------------------- ## 一、循环控制语句的处理 ## 上一篇博客说的都是顺序流程,现在分析一下循环流程的处理,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,构成了上述汇编代码的主要逻辑形式 [CSDN_2]: https://marketing.csdn.net/p/7b6697fd9dd3795a268d1a6f2fe75012 [Link 1]: https://activity.csdn.net/creatActivity?id=10213
还没有评论,来说两句吧...