从反汇编的角度学C/C++之条件判断
Posted 足球中国
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从反汇编的角度学C/C++之条件判断相关的知识,希望对你有一定的参考价值。
由于条件判断中需要用到条件指令,这里为了方便把常见的几个跳转指令放这里参考。
一.if-else if-else条件判断
在C/C++中我们使用使用if-else if -else语句来实现程序根据不同情况来跳转运行。下面通过一个实例来学习其中的内部实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
由上可以看出,在经过if或者else if的时候程序是判断是否不满足条件。在不满足条件的情况下,程序根据情况跳转到相应的地方,如果满足条件程序就会往下执行完相应的指令之后在跳转到整个if-else if-else结构的下一条指令。转换为汇编以后的程序执行流程就如下图所示
二.&&与||
在条件判断中,我们经常使用&&与||。接下来看看他们转成汇编以后的样子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
由上可以看出,对于&&程序会经过两次判断条件是否都成立,任何一次条件不成立都会导致语句块不被执行且第一次判断如果不成立就不会进行第二次判断直接跳过程序块。
而对于||,任何一次条件成立都会导致语句块被执行,且如果第一次条件成立就不会进行第二次判断,直接跳转到条件成立的语句进行执行。
三.对if语句的错误使用
下面列举了两种新手比较容易犯的错误。第一次情况是把=号当做==来进行使用,第二种情况是由于else匹配if是根据最近匹配的原则,由于第一个if成立的语句块没有加导致else匹配了第二个if。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
最终生成的反汇编代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
可以看到,由于把=当成==使用,导致第一个if判断时候先是对x赋值为1,然后在判断x是否等于0。而在第二个由于else没正确配对导致跳转语句不符合预期。最终运行结果如下:
四.switch-case
swich-case在c/c++中也是一种常见的条件判断语法,那么在内存中的表现形式与if-else结构有什么不同呢,请看下面的实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
|
可以看出与if-else if-else结构相比,switch case生成的结构会在最开始就一一判断符合的情况然后跳转到相应的地方。
如果case的情况比较多,像下面这种情况。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
|
此时如果还是一一判断对计算机的性能损耗是比较大的,编译器是否有优化呢?查看对应反汇编如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
|
可以看到这个时候会首先判断是否大于最大的数,如果大于则跳到default执行,如果不大于他会根据与0x00261190偏移找到地址跳转过去,而这个偏移是根据x的值乘以4来计算,所以我们完全可以认为这个地址其实是一个整型数组,里面存储的就是不同情况下应该跳转的地址。查看这个地址的内容如下所示:
可以看到这个数组对应下标0,1,2的值,分别对应了case 0, case 1, case 2的语句块的地址。而由于没case 3,所以下标为3的数组的值保存的就是default的值。其他的case 4 5 6 7 8 9的情况与刚刚的一样。
由此我们可以得出结论,当case语句比较多的时候,编译器会为我们生成一个整型数组,里面保存了各自情况下需要跳转的地址,而程序也会根据偏移得到需要的地址进行跳转。
以上是关于从反汇编的角度学C/C++之条件判断的主要内容,如果未能解决你的问题,请参考以下文章
汇编数据段地址问题 看我的源代码,从反汇编的代码中可以看到段地址DS应该为075A 但是D命令查看的结果不是