悟出点C的东西



刚上大一的时候,C语言的语法都是背会的,考试全是蒙的。即使会点,考完也就忘的差不多了

记得在学switch语句的时候,有这么个语法:

如果要在每个条件语句后边不加break,那么这个条件以下的所有条件都会执行一遍,当时只是背会了,

记住了,原理不懂,这几天通过看《黑客反汇编揭秘》这本书,里面提到这么个东东。。把原理弄懂了

。。

如果写个下面的程序

void main()

{

int a=10;

switch(a) {

case 1:

   printf(“1n”);

   break;

case 10:

   printf(“OKn”);

   break;

default:

   break;

}

}

那么对应的反汇编代码如下:

void main()

5:    {

0040D4D0   push        ebp

0040D4D1   mov         ebp,esp

0040D4D3   sub         esp,48h

0040D4D6   push        ebx

0040D4D7   push        esi

0040D4D8   push        edi

0040D4D9   lea         edi,[ebp-48h]

0040D4DC   mov         ecx,12h

0040D4E1   mov         eax,0CCCCCCCCh

0040D4E6   rep stos    dword ptr [edi]

6:        int a=10;

0040D4E8   mov         dword ptr [ebp-4],0Ah

7:        switch(a) {

0040D4EF   mov         eax,dword ptr [ebp-4]

0040D4F2   mov         dword ptr [ebp-8],eax

0040D4F5   cmp         dword ptr [ebp-8],1

0040D4F9   je          main+33h (0040d503)

0040D4FB   cmp         dword ptr [ebp-8],0Ah

0040D4FF   je          main+42h (0040d512)

0040D501   jmp         main+4Fh (0040d51f)

8:        case 1:

9:            printf(“1n”);

0040D503   push        offset string “1n” (00422f6c)

0040D508   call        printf (0040d750)

0040D50D   add         esp,4

10:           break;

0040D510   jmp         main+4Fh (0040d51f)

11:       case 10:

12:           printf(“OKn”);

0040D512   push        offset string “%sn” (0042210c)

0040D517   call        printf (0040d750)

0040D51C   add         esp,4

13:           break;

14:

15:       default:

16:           break;

17:       }

18:

19:   }

由此可以看到,如果不加break;这条语句,那么就没有下边的jmp那条语句,当然就会顺次向下执行。。

。。。还有一点需要注意,在执行switch(a)这条语句时

0040D4EF   mov         eax,dword ptr [ebp-4]

0040D4F2   mov         dword ptr [ebp-8],eax

对应这么两条汇编代码,这个程序只有一个变量,为什么会有[ebp-8],这可是第二个变量呀?秘密就在

switch这条语句在比较的时候生成自己的临时变量,所以在下边比较的时候会有:

0040D4F5   cmp         dword ptr [ebp-8],1

会和switch生成的临时变量相比较。。。。。