• 逆向初级-C语言(二)


    2.1.C语言的汇编表示

    c语言代码

    int plus(int x,int y)
    {
    	return 0;
    }
    
    void main()
    {
    
    	__asm
    	{
    		mov eax,eax
    	}
    
    	//调用函数
    	plus(1,2);
    
    	return;
    }
    

    汇编代码

    1:
    2:    int plus(int x,int y)
    3:    {
    00401020   push        ebp
    00401021   mov         ebp,esp
    00401023   sub         esp,40h
    00401026   push        ebx
    00401027   push        esi
    00401028   push        edi
    00401029   lea         edi,[ebp-40h]
    0040102C   mov         ecx,10h
    00401031   mov         eax,0CCCCCCCCh
    00401036   rep stos    dword ptr [edi]
    4:        return 0;
    00401038   xor         eax,eax
    5:    }
    0040103A   pop         edi
    0040103B   pop         esi
    0040103C   pop         ebx
    0040103D   mov         esp,ebp
    0040103F   pop         ebp
    00401040   ret
    --- No source file  -------------------------------------------------------------------------------------------------------------------------------------
    00401041   int         3
    00401042   int         3
    00401043   int         3
    00401044   int         3
    0040104F   int         3
    --- C:Program FilesMicrosoft Visual StudioMyProjects11	est.cpp  ------------------------------------------------------------------------------------
    6:
    7:    void main()
    8:    {
    00401050   push        ebp
    00401051   mov         ebp,esp
    00401053   sub         esp,40h
    00401056   push        ebx
    00401057   push        esi
    00401058   push        edi
    00401059   lea         edi,[ebp-40h]
    0040105C   mov         ecx,10h
    00401061   mov         eax,0CCCCCCCCh
    00401066   rep stos    dword ptr [edi]
    9:        plus(1,2);    //调用函数
    00401068   push        2
    0040106A   push        1
    0040106C   call        @ILT+0(plus) (00401005)
    00401071   add         esp,8
    10:
    11:       return;
    12:   }
    00401074   pop         edi
    00401075   pop         esi
    00401076   pop         ebx
    00401077   add         esp,40h
    0040107A   cmp         ebp,esp
    0040107C   call        __chkesp (004010a0)
    00401081   mov         esp,ebp
    00401083   pop         ebp
    00401084   ret
    --- No source file  -------------------------------------------------------------------------------------------------------------------------------------
    00401085   int         3
    
    
    

    2.2.参数传递与返回值

    1、函数定义

    返回类型函数名(参数列表)
    {
    	return
    }
    
    例子:
    int plus(int x,int y)
    {
        return x+y;
    }
    

    2.画堆栈图

    int plus(int x,int y)
    {
    	return x+y;
    }
    
    void main()
    {
    	__asm
    	{
    		mov eax,eax     //断点调试   F7,F5,右键Go To Disassembly. F10单步,call按F11
    	}
    
    	plus(1,2);    
    
    	return;
    }
    

    image
    3.汇编代码

    1:
    2:    int plus(int x,int y)
    3:    {
    00401020   push        ebp
    00401021   mov         ebp,esp
    00401023   sub         esp,40h                       //提升堆栈
    00401026   push        ebx
    00401027   push        esi
    00401028   push        edi                           //保存要用到的寄存器的值
    00401029   lea         edi,[ebp-40h]
    0040102C   mov         ecx,10h                       //ecx=10h,ecx是计数器  
    00401031   mov         eax,0CCCCCCCCh                //eax=CCCCCCCC
    00401036   rep stos    dword ptr [edi]              //把eax的值写到[edi],写的次数:ecx的值
    4:        return x+y;
    00401038   mov         eax,dword ptr [ebp+8]         //第一个参数的值,eax=1
    0040103B   add         eax,dword ptr [ebp+0Ch]       //第一个参数+第二个参数  eax=1+2
    5:    }
    0040103E   pop         edi
    0040103F   pop         esi
    00401040   pop         ebx                           
    00401041   mov         esp,ebp
    00401043   pop         ebp                            //还原堆栈
    00401044   ret                                        //eip=00401083,  esp+4
    --- No source file  -------------------------------------------------------------------------------------------------------------------------------------
    00401045   int         3
    00401046   int         3
    
    --- C:Program FilesMicrosoft Visual StudioMyProjects11	est.cpp  ------------------------------------------------------------------------------------
    6:
    7:    void main()
    8:    {
    00401050   push        ebp
    00401051   mov         ebp,esp
    00401053   sub         esp,40h
    00401056   push        ebx
    00401057   push        esi
    00401058   push        edi
    00401059   lea         edi,[ebp-40h]
    0040105C   mov         ecx,10h
    00401061   mov         eax,0CCCCCCCCh
    00401066   rep stos    dword ptr [edi]
    9:        __asm
    10:       {
    11:           mov eax,eax
    00401068   mov         eax,eax
    12:       }
    13:
    14:       plus(1,2);
    0040106A   push        2								//通过堆栈传参数				
    0040106C   push        1
    0040106E   call        @ILT+0(plus) (00401005)
    00401073   add         esp,8                           //还原堆栈
    15:
    16:       return;
    17:   }
    00401076   pop         edi
    00401077   pop         esi
    00401078   pop         ebx
    00401079   add         esp,40h
    0040107C   cmp         ebp,esp
    0040107E   call        __chkesp (004010a0)
    00401083   mov         esp,ebp
    00401085   pop         ebp
    00401086   ret
    --- No source file  -------------------------------------------------------------------------------------------------------------------------------------
    00401087   int         3
    00401088   int         3
    

    3、参数是如何传递的
    C语言中参数传递:堆栈传参数从右到左

    4、返回值存在哪里?返回值用了吗?
    C语言中,返回值存储在EAX中

    2.3.变量

    1、声明变量
    变量类型变量名;
    变量类型用来说明宽度是多大
    int 4个字节
    short 2个字节
    char 1个字节

    变量名的命名规则:
    1、只能以字母、数字、下划线组成,且第一个字母必须是字母或下划线
    2、区分大小写
    3、不能使用C语言的关键字

    2、全局变量:
    1)编译的时候就已经确定了内存地址和宽度,变量名就是内存地址的别名。
    2)如果不重写编译,全局变量的内存地址不变。游戏外挂中的找“基址”,其实就
    是找全局变量。|
    3)全局变量中的值任何程序都可以改,是公用的。
    例子: CE搜索基址

    C语言代码

    #include <windows.h>
    #include <stdio.h>
    
    int x;
    
    void main()
    {
    	x = 1234567;
    
    	while(1)
    	{
    		Sleep(3000);
    		printf("%d
    ",x);
    	}
    
    	return;
    }
    

    image
    3、局部变量
    1)局部变量是函数内部申请的,如果函数没有执行,那么局部变量没有内存空间。
    2)局部变量的内存是在堆栈中分配的,程序执行时才分配。我们无法预知程序何时
    执行,这也就意味着,我们无法确定局部变量的内存地址。
    3)因为局部变量地址内存是不确定的,所以,局部变量只能在函数内部使用,其他
    函数不能使用。

    2.4.变量与参数的内存布局

    c语言代码

    int plus(int x,int y)
    {
    	int z = x + y;
    	return z;
    }
    
    void main()
    {
    	int r;
    	r = plus(1,2);
    	return;
    } 
    

    汇编代码

    1:
    2:    int plus(int x,int y)
    3:    {
    00401020   push        ebp
    00401021   mov         ebp,esp
    00401023   sub         esp,44h
    00401026   push        ebx
    00401027   push        esi
    00401028   push        edi
    00401029   lea         edi,[ebp-44h]
    0040102C   mov         ecx,11h
    00401031   mov         eax,0CCCCCCCCh
    00401036   rep stos    dword ptr [edi]
    4:        int z = x + y;
    00401038   mov         eax,dword ptr [ebp+8]
    0040103B   add         eax,dword ptr [ebp+0Ch]
    0040103E   mov         dword ptr [ebp-4],eax            //[ebp-4]存放局部变量
    5:        return z;
    00401041   mov         eax,dword ptr [ebp-4]
    6:    }
    00401044   pop         edi
    00401045   pop         esi
    00401046   pop         ebx
    00401047   mov         esp,ebp
    00401049   pop         ebp
    0040104A   ret
    --- No source file  -----------------------------------------------------------------------------------------------
    0040104B   int         3
    0040104C   int         3
    
    --- C:Program FilesMicrosoft Visual StudioMyProjects11	est.cpp  ----------------------------------------------
    7:
    8:    void main()
    9:    {
    00401060   push        ebp
    00401061   mov         ebp,esp
    00401063   sub         esp,44h
    00401066   push        ebx
    00401067   push        esi
    00401068   push        edi
    00401069   lea         edi,[ebp-44h]
    0040106C   mov         ecx,11h
    00401071   mov         eax,0CCCCCCCCh
    00401076   rep stos    dword ptr [edi]
    10:       int r;
    11:       r = plus(1,2);
    00401078   push        2
    0040107A   push        1
    0040107C   call        @ILT+0(plus) (00401005)
    00401081   add         esp,8
    00401084   mov         dword ptr [ebp-4],eax
    12:       return;
    13:   }
    00401087   pop         edi
    00401088   pop         esi
    00401089   pop         ebx
    0040108A   add         esp,44h
    0040108D   cmp         ebp,esp
    0040108F   call        __chkesp (004010b0)
    00401094   mov         esp,ebp
    00401096   pop         ebp
    00401097   ret
    --- No source file  -----------------------------------------------------------------------------------------------
    00401098   int         3
    00401099   int         3
    
    

    堆栈图
    image
    1.5.函数嵌套调用的内存布局

    C语言代码

    #include<stdio.h>
    
    int plus1(int x,int y)
    {
    	return x+y;
    }
    
    int plus(int x,int y,int z)
    {
    	int m = plus1(x,y);
    	return m+z;
    }
    
    void main()
    {
    	int r;
    	r = plus(1,2,3);
    	printf("%d",r);
    	return;
    }
    

    汇编代码

    1:    #include<stdio.h>
    2:
    3:    int plus1(int x,int y)
    4:    {
    00401020   push        ebp
    00401021   mov         ebp,esp
    00401023   sub         esp,40h
    00401026   push        ebx
    00401027   push        esi
    00401028   push        edi
    00401029   lea         edi,[ebp-40h]
    0040102C   mov         ecx,10h
    00401031   mov         eax,0CCCCCCCCh
    00401036   rep stos    dword ptr [edi]
    5:        return x+y;
    00401038   mov         eax,dword ptr [ebp+8]
    0040103B   add         eax,dword ptr [ebp+0Ch]
    6:    }
    0040103E   pop         edi
    0040103F   pop         esi
    00401040   pop         ebx
    00401041   mov         esp,ebp
    00401043   pop         ebp
    00401044   ret
    --- No source file  -----------------------------------------------------------------------------------------------
    00401045   int         3
    00401046   int         3
    
    7:
    8:    int plus(int x,int y,int z)
    9:    {
    00401060   push        ebp
    00401061   mov         ebp,esp
    00401063   sub         esp,44h
    00401066   push        ebx
    00401067   push        esi
    00401068   push        edi
    00401069   lea         edi,[ebp-44h]
    0040106C   mov         ecx,11h
    00401071   mov         eax,0CCCCCCCCh
    00401076   rep stos    dword ptr [edi]                 
    10:       int m = plus1(x,y);
    00401078   mov         eax,dword ptr [ebp+0Ch]
    0040107B   push        eax
    0040107C   mov         ecx,dword ptr [ebp+8]
    0040107F   push        ecx
    00401080   call        @ILT+10(plus) (0040100f)
    00401085   add         esp,8
    00401088   mov         dword ptr [ebp-4],eax
    11:       return m+z;
    0040108B   mov         eax,dword ptr [ebp-4]
    0040108E   add         eax,dword ptr [ebp+10h]
    12:   }
    00401091   pop         edi
    00401092   pop         esi
    00401093   pop         ebx
    00401094   add         esp,44h
    00401097   cmp         ebp,esp
    00401099   call        __chkesp (004010b0)
    0040109E   mov         esp,ebp
    004010A0   pop         ebp
    004010A1   ret
    --- No source file  -----------------------------------------------------------------------------------------------
    004010A2   int         3
    004010A3   int         3
    
    13:
    14:   void main()
    15:   {
    0040B500   push        ebp
    0040B501   mov         ebp,esp
    0040B503   sub         esp,44h
    0040B506   push        ebx
    0040B507   push        esi
    0040B508   push        edi
    0040B509   lea         edi,[ebp-44h]
    0040B50C   mov         ecx,11h
    0040B511   mov         eax,0CCCCCCCCh
    0040B516   rep stos    dword ptr [edi]     
    16:       int r;
    17:       r = plus(1,2,3);
    0040B518   push        3
    0040B51A   push        2
    0040B51C   push        1                  //传三个参数
    0040B51E   call        @ILT+15(plus) (00401014)
    0040B523   add         esp,0Ch
    0040B526   mov         dword ptr [ebp-4],eax
    18:       printf("%d",r);
    0040B529   mov         eax,dword ptr [ebp-4]
    0040B52C   push        eax
    0040B52D   push        offset string "%d" (0041f10c)
    0040B532   call        printf (0040b770)
    0040B537   add         esp,8
    19:       return;
    20:   }
    0040B53A   pop         edi
    0040B53B   pop         esi
    0040B53C   pop         ebx
    0040B53D   add         esp,44h
    0040B540   cmp         ebp,esp
    0040B542   call        __chkesp (004010b0)
    0040B547   mov         esp,ebp
    0040B549   pop         ebp
    0040B54A   ret
    --- No source file  -----------------------------------------------------------------------------------------------
    0040B54B   int         3
    0040B54C   int         3
    

    堆栈图
    image

    2.5.整数类型

    1、整数类型的宽度:

    char、short、 int、 long

    char 8BIT 1字节 0~ 0xFF
    short 16BIT 2字节 0~ 0xFFFF
    int 32BIT 4字节 0 ~ 0xFFFFFFFF
    long 32BIT 4字节 0 ~ 0xFFFFFFFF

    特别说明:
    int在16计算机中与short宽度-样,在32以上的计算机中与long同

    2、存储格式:
    charx=1; //0000 0001 0x01
    charx= 1; //1111 1111 0xFF

    3、有符号与无符号数(signed、 unsigned)
    1)什么时候使用有符号、无符号
    2)有符号与无符号的区别:
    <1>正确理解有符号数与无符号数
    <2>拓展时与比较时才有区别

    2.6.if语句

    C语言代码

    #include<stdio.h>
    #include<windows.h>
    
    void main()
    {
    	int x = 10;
    	int y = 20;
    
    	if(x>y)
    	{
    		printf("+++++
    ");
    	}
    	else
    	{
    		printf("------
    ");
    	}
    
    	return;
    } 
    

    汇编代码

    1:    #include<stdio.h>
    2:    #include<windows.h>
    3:
    4:    void main()
    5:    {
    00401010   push        ebp
    00401011   mov         ebp,esp
    00401013   sub         esp,48h
    00401016   push        ebx
    00401017   push        esi
    00401018   push        edi
    00401019   lea         edi,[ebp-48h]
    0040101C   mov         ecx,12h
    00401021   mov         eax,0CCCCCCCCh
    00401026   rep stos    dword ptr [edi]
    6:        int x = 10;
    00401028   mov         dword ptr [ebp-4],0Ah
    7:        int y = 20;
    0040102F   mov         dword ptr [ebp-8],14h
    8:
    9:        if(x>y)
    00401036   mov         eax,dword ptr [ebp-4]
    00401039   cmp         eax,dword ptr [ebp-8]
    0040103C   jle         main+3Dh (0040104d)
    10:       {
    11:           printf("+++++
    ");
    0040103E   push        offset string "+++++
    " (00420028)
    00401043   call        printf (00401090)
    00401048   add         esp,4
    12:       }
    13:       else
    0040104B   jmp         main+4Ah (0040105a)
    14:       {
    15:           printf("------
    ");
    0040104D   push        offset string "------
    " (0042001c)
    00401052   call        printf (00401090)
    00401057   add         esp,4
    16:       }
    17:
    18:       return;
    19:   }
    0040105A   pop         edi
    0040105B   pop         esi
    0040105C   pop         ebx
    0040105D   add         esp,48h
    00401060   cmp         ebp,esp
    00401062   call        __chkesp (00401110)
    00401067   mov         esp,ebp
    00401069   pop         ebp
    0040106A   ret
    --- No source file  -----------------------------------------------------------------------------------------------
    0040106B   int         3
    0040106C   int         3
    
    

    2.7.switch语句

    当分支条件比较多得时候switch比if语句高效很多。

    case条件按顺序时候的汇编代码

    C语言代码

    #include<stdio.h>
    #include<windows.h>
    
    void Myprint(int x)
    {
    	switch(x)
    	{
    	case 1:
    		printf("A
    ");
    		break;
    	case 2:
    		printf("B
    ");
    		break;
    	case 3:
    		printf("C
    ");
    		break;
    	case 4:
    		printf("D
    ");
    		break;
    	case 5:
    		printf("E
    ");
    		break;
    	}
    }
    
    void main()
    {
    	Myprint(3);
    
    	return ;
    } 
    

    汇编语言代码

    1:    #include<stdio.h>
    2:    #include<windows.h>
    3:
    4:    void Myprint(int x)
    5:    {
    00401020   push        ebp
    00401021   mov         ebp,esp
    00401023   sub         esp,44h
    00401026   push        ebx
    00401027   push        esi
    00401028   push        edi
    00401029   lea         edi,[ebp-44h]
    0040102C   mov         ecx,11h
    00401031   mov         eax,0CCCCCCCCh
    00401036   rep stos    dword ptr [edi]
    6:        switch(x)
    7:        {
    00401038   mov         eax,dword ptr [ebp+8]
    0040103B   mov         dword ptr [ebp-4],eax
    0040103E   mov         ecx,dword ptr [ebp-4]
    00401041   sub         ecx,1
    00401044   mov         dword ptr [ebp-4],ecx
    00401047   cmp         dword ptr [ebp-4],4
    0040104B   ja          $L42195+0Dh (004010a0)
    0040104D   mov         edx,dword ptr [ebp-4]
    00401050   jmp         dword ptr [edx*4+4010B1h]
    8:        case 1:
    9:            printf("A
    ");
    00401057   push        offset string "A
    " (0042002c)
    0040105C   call        printf (00401130)
    00401061   add         esp,4
    10:           break;
    00401064   jmp         $L42195+0Dh (004010a0)
    11:       case 2:
    12:           printf("B
    ");
    00401066   push        offset string "B
    " (00420028)
    0040106B   call        printf (00401130)
    00401070   add         esp,4
    13:           break;
    00401073   jmp         $L42195+0Dh (004010a0)
    14:       case 3:
    15:           printf("C
    ");
    00401075   push        offset string "C
    " (00420024)
    0040107A   call        printf (00401130)
    0040107F   add         esp,4
    16:           break;
    00401082   jmp         $L42195+0Dh (004010a0)
    17:       case 4:
    18:           printf("D
    ");
    00401084   push        offset string "D
    " (00420020)
    00401089   call        printf (00401130)
    0040108E   add         esp,4
    19:           break;
    00401091   jmp         $L42195+0Dh (004010a0)
    20:       case 5:
    21:           printf("E
    ");
    00401093   push        offset string "E
    " (0042001c)
    00401098   call        printf (00401130)
    0040109D   add         esp,4
    22:           break;
    23:       }
    24:   }
    004010A0   pop         edi
    004010A1   pop         esi
    004010A2   pop         ebx
    004010A3   add         esp,44h
    004010A6   cmp         ebp,esp
    004010A8   call        __chkesp (004011b0)
    004010AD   mov         esp,ebp
    004010AF   pop         ebp
    004010B0   ret
    004010B1   push        edi
    004010B2   adc         byte ptr [eax],al
    004010B5   adc         byte ptr [eax],al
    004010B9   jne         Myprint+0ABh (004010cb)
    004010BB   inc         eax
    004010BC   add         byte ptr [eax+edx+10930040h],al
    004010C3   inc         eax
    004010C4   add         ah,cl
    --- No source file  -----------------------------------------------------------------------------------------------
    004010C6   int         3
    004010C7   int         3
    
    

    case条件不按顺序时候的汇编代码

    c语言代码

    #include<stdio.h>
    #include<windows.h>
    
    void Myprint(int x)
    {
    	switch(x)
    	{
    	case 1:
    		printf("A
    ");
    		break;
    	case 2:
    		printf("B
    ");
    		break;
    	case 4:
    		printf("C
    ");
    		break;
    	case 7:
    		printf("D
    ");
    		break;
    	case 8:
    		printf("E
    ");
    		break;
    	}
    }
    
    void main()
    {
    	Myprint(3);
    
    	return ;
    } 
    

    汇编代码

    :    #include<stdio.h>
    2:    #include<windows.h>
    3:
    4:    void Myprint(int x)
    5:    {
    00401020   push        ebp
    00401021   mov         ebp,esp
    00401023   sub         esp,44h
    00401026   push        ebx
    00401027   push        esi
    00401028   push        edi
    00401029   lea         edi,[ebp-44h]
    0040102C   mov         ecx,11h
    00401031   mov         eax,0CCCCCCCCh
    00401036   rep stos    dword ptr [edi]
    6:        switch(x)
    7:        {
    00401038   mov         eax,dword ptr [ebp+8]
    0040103B   mov         dword ptr [ebp-4],eax
    0040103E   mov         ecx,dword ptr [ebp-4]
    00401041   sub         ecx,1
    00401044   mov         dword ptr [ebp-4],ecx
    00401047   cmp         dword ptr [ebp-4],7
    0040104B   ja          $L42196+0Dh (004010a0)
    0040104D   mov         edx,dword ptr [ebp-4]
    00401050   jmp         dword ptr [edx*4+4010B1h]
    8:        case 1:
    9:            printf("A
    ");
    00401057   push        offset string "A
    " (0042002c)
    0040105C   call        printf (00401130)
    00401061   add         esp,4
    10:           break;
    00401064   jmp         $L42196+0Dh (004010a0)
    11:       case 2:
    12:           printf("B
    ");
    00401066   push        offset string "B
    " (00420028)
    0040106B   call        printf (00401130)
    00401070   add         esp,4
    13:           break;
    00401073   jmp         $L42196+0Dh (004010a0)
    14:       case 4:
    15:           printf("C
    ");
    00401075   push        offset string "C
    " (00420024)
    0040107A   call        printf (00401130)
    0040107F   add         esp,4
    16:           break;
    00401082   jmp         $L42196+0Dh (004010a0)
    17:       case 7:
    18:           printf("D
    ");
    00401084   push        offset string "D
    " (00420020)
    00401089   call        printf (00401130)
    0040108E   add         esp,4
    19:           break;
    00401091   jmp         $L42196+0Dh (004010a0)
    20:       case 8:
    21:           printf("E
    ");
    00401093   push        offset string "E
    " (0042001c)
    00401098   call        printf (00401130)
    0040109D   add         esp,4
    22:           break;
    23:       }
    24:   }
    004010A0   pop         edi
    004010A1   pop         esi
    004010A2   pop         ebx
    004010A3   add         esp,44h
    004010A6   cmp         ebp,esp
    004010A8   call        __chkesp (004011b0)
    004010AD   mov         esp,ebp
    004010AF   pop         ebp
    004010B0   ret
    004010B1   push        edi
    004010B2   adc         byte ptr [eax],al
    004010B5   adc         byte ptr [eax],al
    004010B9   mov         al,[75004010]
    004010BE   adc         byte ptr [eax],al
    004010C1   mov         al,[A0004010]
    004010C6   adc         byte ptr [eax],al
    004010C9   test        byte ptr [eax],dl
    004010CB   inc         eax
    004010CC   add         byte ptr [ebx-33FFBFF0h],dl
    --- No source file  -----------------------------------------------------------------------------------------------
    004010D2   int         3
    004010D3   int         3
    
    

    case条件中间不连续(3,5,6)的地方,会填充为default的地址,
    image

    2.8.for循环

    C语言代码

    #include<stdio.h>
    #include<windows.h>
    
    void Myprint()
    {
    	int i;
    	for(i=0;i<10;i++)
    	{
    		printf("%d
    ",i);
    	}
    }
    
    void main()
    {
    	Myprint();
    
    	return ;
    } 
    

    汇编代码

    1:    #include<stdio.h>
    2:    #include<windows.h>
    3:
    4:    void Myprint()
    5:    {
    00401020   push        ebp
    00401021   mov         ebp,esp
    00401023   sub         esp,44h
    00401026   push        ebx
    00401027   push        esi
    00401028   push        edi
    00401029   lea         edi,[ebp-44h]
    0040102C   mov         ecx,11h
    00401031   mov         eax,0CCCCCCCCh
    00401036   rep stos    dword ptr [edi]
    6:        int i;
    7:        for(i=0;i<10;i++)
    00401038   mov         dword ptr [ebp-4],0
    0040103F   jmp         Myprint+2Ah (0040104a)
    00401041   mov         eax,dword ptr [ebp-4]
    00401044   add         eax,1
    00401047   mov         dword ptr [ebp-4],eax
    0040104A   cmp         dword ptr [ebp-4],0Ah
    0040104E   jge         Myprint+43h (00401063)
    8:        {
    9:            printf("%d
    ",i);
    00401050   mov         ecx,dword ptr [ebp-4]
    00401053   push        ecx
    00401054   push        offset string "E
    " (0042001c)
    00401059   call        printf (00401130)
    0040105E   add         esp,8
    10:       }
    00401061   jmp         Myprint+21h (00401041)
    11:   }
    00401063   pop         edi
    00401064   pop         esi
    00401065   pop         ebx
    00401066   add         esp,44h
    00401069   cmp         ebp,esp
    0040106B   call        __chkesp (004011b0)
    00401070   mov         esp,ebp
    00401072   pop         ebp
    00401073   ret
    --- No source file  ---------------------------------------------------------------------------------------------------------------------
    00401074   int         3
    00401075   int         3
    
    

    2.9.数组

    C语言代码

    #include<stdio.h>
    #include<windows.h>
    
    
    void main()
    {
    	int age[5]={1,2,3,4,5};
    	int x,y;
    	x = age[0];
    	age[1]=6;
    	y = age[1];
    	printf("%d
    %d",x,y);
    	return ;
    } 
    

    汇编代码

    1:    #include<stdio.h>
    2:    #include<windows.h>
    3:
    4:
    5:    void main()
    6:    {
    00401020   push        ebp
    00401021   mov         ebp,esp
    00401023   sub         esp,5Ch
    00401026   push        ebx
    00401027   push        esi
    00401028   push        edi
    00401029   lea         edi,[ebp-5Ch]
    0040102C   mov         ecx,17h
    00401031   mov         eax,0CCCCCCCCh
    00401036   rep stos    dword ptr [edi]
    7:        int age[5]={1,2,3,4,5};
    00401038   mov         dword ptr [ebp-14h],1
    0040103F   mov         dword ptr [ebp-10h],2
    00401046   mov         dword ptr [ebp-0Ch],3
    0040104D   mov         dword ptr [ebp-8],4
    00401054   mov         dword ptr [ebp-4],5
    8:        int x,y;
    9:        x = age[0];
    0040105B   mov         eax,dword ptr [ebp-14h]
    0040105E   mov         dword ptr [ebp-18h],eax
    10:       age[1]=6;
    00401061   mov         dword ptr [ebp-10h],6
    11:       y = age[1];
    00401068   mov         ecx,dword ptr [ebp-10h]
    0040106B   mov         dword ptr [ebp-1Ch],ecx
    12:       printf("%d
    %d",x,y);
    0040106E   mov         edx,dword ptr [ebp-1Ch]
    00401071   push        edx
    00401072   mov         eax,dword ptr [ebp-18h]
    00401075   push        eax
    00401076   push        offset string "%d
    %d" (0042001c)
    0040107B   call        printf (00401130)
    00401080   add         esp,0Ch
    13:       return ;
    14:   }
    00401083   pop         edi
    00401084   pop         esi
    00401085   pop         ebx
    00401086   add         esp,5Ch
    00401089   cmp         ebp,esp
    0040108B   call        __chkesp (004011b0)
    00401090   mov         esp,ebp
    00401092   pop         ebp
    00401093   ret
    --- No source file  ---------------------------------------------------------------------------------------------------------------------
    00401094   int         3
    00401095   int         3
    
    

    2.10.多维数组

    C语言代码

    #include<stdio.h>
    #include<windows.h>
    
    
    void main()
    {
    	int arr[3][4] = 
    	{
    		{1,2,3,4},
    		{5,6,7,8},
    		{9,10,11,12}
    	};
    
    	return ;
    } 
    

    汇编代码

    1:    #include<stdio.h>
    2:    #include<windows.h>
    3:
    4:
    5:    void main()
    6:    {
    00401010   push        ebp
    00401011   mov         ebp,esp
    00401013   sub         esp,70h
    00401016   push        ebx
    00401017   push        esi
    00401018   push        edi
    00401019   lea         edi,[ebp-70h]
    0040101C   mov         ecx,1Ch
    00401021   mov         eax,0CCCCCCCCh
    00401026   rep stos    dword ptr [edi]
    7:        int arr[3][4] =
    8:        {
    9:            {1,2,3,4},
    00401028   mov         dword ptr [ebp-30h],1
    0040102F   mov         dword ptr [ebp-2Ch],2
    00401036   mov         dword ptr [ebp-28h],3
    0040103D   mov         dword ptr [ebp-24h],4
    10:           {5,6,7,8},
    00401044   mov         dword ptr [ebp-20h],5
    0040104B   mov         dword ptr [ebp-1Ch],6
    00401052   mov         dword ptr [ebp-18h],7
    00401059   mov         dword ptr [ebp-14h],8
    11:           {9,10,11,12}
    00401060   mov         dword ptr [ebp-10h],9
    00401067   mov         dword ptr [ebp-0Ch],0Ah
    0040106E   mov         dword ptr [ebp-8],0Bh
    00401075   mov         dword ptr [ebp-4],0Ch
    12:       };
    13:
    14:       return ;
    15:   }
    0040107C   pop         edi
    0040107D   pop         esi
    0040107E   pop         ebx
    0040107F   mov         esp,ebp
    00401081   pop         ebp
    00401082   ret
    --- No source file  ---------------------------------------------------------------------------------------------------------------------
    00401083   int         3
    00401084   int         3
    
    

    2.11.结构体

    结构体类型的定义:

    struct类型名{
    	//可以定义多种类型
    	inta;
    	char b;
    	short c;
    };
    

    <1> char/int/数组等是编译器已经认识的类型:内置类型
    <2>结构体是编译器不认识的,用的时候需要告诉编译器-声:自定义类型
    <3>.上面的代码仅仅是告诉编译器我们自己定义的类型是什么样的,本身并不占用内存。

    定义结构体类型的时候,直接定义变量

    struct stPoint{
    	int x;
    	int y;
    }point1 ,point2,point3;
    

    //这种方式是分配内存的,因为不仅仅是定义新的类型,还定义了3个全局变量

    2.12.字节对齐

    1.什么是字节对齐呢?
    char X;
    short y;|
    intz;

    字节对齐:
    一个变量占用n个字节,则该变量的起始地址必须是n的整数倍,即:存放起始地址% n=0。

    如果是结构体,那么结构体的起始地址是其最宽数据类型成员的整数倍。

    2.结构体字节对齐占用空间大小

    #include<stdio.h>
    #include<windows.h>
    
    struct test1{
    	char a;
    	int b;
    };
    
    struct test2{
    	char c;
    	double d;
    };
    
    int check()
    {
    	printf("%d
    ",sizeof(test1));    //8
    	printf("%d
    ",sizeof(test2));    //16
    	return 0;
    }
    
    
    void main()
    {
    	check();
    	getchar();
    	return ;
    } 
    

    3.当对空间要求较高的时候,可以通过#pragma pack(n)来改变结构体成员的对齐方式

    #pragma pack(1)
    structTest{
    	char a;
    	int b;
    };
    #pragma pack()
    

    <1> #pragma pack(n)中n用来设定变量以n字节对齐方式,可以设定的值包括: 1、2、4、8,VC编译器默认是8。
    <2>若需取消强制对齐方式,则可用命令#pragma pack()

    <3>结构体大总大小: N = Min(最大成员,对齐参数)是N的整数倍
    image

    2.13.指针类型

    1、定义带“*”类型的变量

    1、带有**的变量类型的标准写法:变量类型* * 变量名。
    2、任何类型都可以带* 加上* 以后是新的类型,统称“指针类型”。
    3、*可以是任意多个。

    2、指针宽度

    指针类型的变量宽度永远是4字节、无论类型是什么,无论有几个*。

    char* a
    short* b
    int* c
    
    

    3、指针类型的自加和自减
    1、不带类型的变量,++或者-都是加1或者减1
    2、带
    类型的变量,++或者-新增(减少)的数量是去掉-一个*后变量的宽度

    #include<stdio.h>
    #include<windows.h>
    
    void main()
    {
    
    	char* a;
    	short* b;
    	int* c;
    
    	a = (char*)100;
    	b = (short*)100;
    	c = (int*)100;
    	a++;   //减掉一个*后就是char的宽度,1
    	b++;   //减掉一个*后就是short的宽度,2
    	c++;   //减掉一个*后就是int的宽度,4
    	printf("%d %d %d
    ",a,b,c);   //101 102 104
    		
    	system("pause");
    	return ;
    } 
    
    #include<stdio.h>
    #include<windows.h>
    
    void main()
    {
    
    	char** a;
    	short** b;
    	int** c;
    
    	a = (char**)100;
    	b = (short**)100;
    	c = (int**)100;
    	a++;   //减掉一个*后就是char*的宽度,4
    	b++;   //减掉一个*后就是short*的宽度,4
    	c++;   //减掉一个*后就是int*的宽度,4
    	printf("%d %d %d
    ",a,b,c);   //104 104 104
    		
    	system("pause");
    	return ;
    } 
    

    4、指针类型的加减运算
    1、指针类型的变量可以加、减-一个整数,但不能乘或者除.
    2、指针类型变量与其他整数相加或者相减时:
    指针类型变量+N = 指针类型变量+ N * (去掉-一个* 后类型的宽度)
    指针类型变量-N = 指针类型变量- N * (去掉-一个 * 后类型的宽度)

    #include<stdio.h>
    #include<windows.h>
    
    void main()
    {
    	char* a;
    	short* b;
    	int* c;
    
    	a = (char*)100;
    	b = (short*)100;
    	c = (int*)100;
    	a = a + 5;     // a = 100+(1x5)
    	b = b + 5;     // b = 100+(2x5)
    	c = c + 5;     // c = 100+(4x5)
    	printf("%d %d %d
    ",a,b,c);   //105 110 120
    		
    	system("pause");
    	return ;
    } 
    
    #include<stdio.h>
    #include<windows.h>
    
    void main()
    {
    	char** a;
    	short** b;
    	int** c;
    
    	a = (char**)100;
    	b = (short**)100;
    	c = (int**)100;
    	a = a + 5;     // a = 100+(4x5)
    	b = b + 5;     // b = 100+(4x5)
    	c = c + 5;     // c = 100+(4x5)
    	printf("%d %d %d
    ",a,b,c);   //120 120 120
    		
    	system("pause");
    	return ;
    } 
    

    5、指针类型可以做大小比较

    #include<stdio.h>
    #include<windows.h>
    
    void main()
    {
    
    	char* a;
    	char* b;
    
    	a = (char*)200;
    	b = (char*)100;
    
    	if(a>b)
    	{
    		printf("1
    ");     //1
    	}
    	else
    	{
    		printf("2
    ");
    	}
    		
    	system("pause");
    	return ;
    } 
    

    2.14.&的使用

    &是取地址符,任何变量都可以使用&来获取地址,但不能用在常量上。

    指针变量赋值

    #include<stdio.h>
    #include<windows.h>
    
    void main()
    {
    
    	char x;
    	char* p1;
    	char** p2;
    	char*** p3;
    	char**** p4;
    
    	p1 = &x;        //char*
    	p2 = &p1;		//char**
    	p3 = &p2;		//cahr***
    	p4 = &p3;		//char****
    	
    	system("pause");
    	return ;
    } 
    

    2.15.取值运算符

    1、 * 指针类型 的类型

    *加指针类型 的类型是 指针类型减去一个 *

    #include<stdio.h>
    #include<windows.h>
    
    void main()
    {
    	int*** a;
    	int** b;
    	int* c;
    
    	int x = *(a);		//a是int***类型,*(a)是int**类型 
    	int y = *(b);		//b是int**类型,*(b)是int*类型
    	int z = *(c);		//c是int*类型,*(c)是int类型
    		
    	system("pause");
    	return ;
    } 
    

    取值运算符举例

    C语言代码

    #include<stdio.h>
    #include<windows.h>
    
    int x = 1;
    int* p1;
    int** p2;
    int*** p3;
    
    void main()
    {
    	p1 = &x;
    	p2 = &p1;
    	p3=&p2;
    
    	int r = *(*(*(p3)));
    	printf("%d
    ",r);
    
    	system("pause");
    	return ;
    } 
    

    汇编代码

    1:    #include<stdio.h>
    2:    #include<windows.h>
    3:
    4:    int x = 1;
    5:    int* p1;
    6:    int** p2;
    7:    int*** p3;
    8:
    9:    void main()
    10:   {
    00401010   push        ebp
    00401011   mov         ebp,esp
    00401013   sub         esp,44h
    00401016   push        ebx
    00401017   push        esi
    00401018   push        edi
    00401019   lea         edi,[ebp-44h]
    0040101C   mov         ecx,11h
    00401021   mov         eax,0CCCCCCCCh
    00401026   rep stos    dword ptr [edi]
    11:       p1 = &x;
    00401028   mov         dword ptr [p1 (004255ec)],offset x (00424a30)
    12:       p2 = &p1;
    00401032   mov         dword ptr [p2 (004255f0)],offset p1 (004255ec)
    13:       p3=&p2;
    0040103C   mov         dword ptr [p3 (004255f4)],offset p2 (004255f0)
    14:
    15:       int r = *(*(*(p3)));
    00401046   mov         eax,[p3 (004255f4)]
    0040104B   mov         ecx,dword ptr [eax]
    0040104D   mov         edx,dword ptr [ecx]
    0040104F   mov         eax,dword ptr [edx]
    00401051   mov         dword ptr [ebp-4],eax
    16:       printf("%d
    ",r);
    00401054   mov         ecx,dword ptr [ebp-4]
    00401057   push        ecx
    00401058   push        offset string "%d
    " (00422024)
    0040105D   call        printf (004011b0)
    00401062   add         esp,8
    17:
    18:       system("pause");
    00401065   push        offset string "pause" (0042201c)
    0040106A   call        system (004010a0)
    0040106F   add         esp,4
    19:       return ;
    20:   }
    00401072   pop         edi
    00401073   pop         esi
    00401074   pop         ebx
    00401075   add         esp,44h
    00401078   cmp         ebp,esp
    0040107A   call        __chkesp (00401230)
    0040107F   mov         esp,ebp
    00401081   pop         ebp
    00401082   ret
    --- No source file  --------------------------------------------------------------------------------------------------------------------------------
    00401083   int         3
    
    

    2.16.数组参数传递

    1、数组作为参数:****

    1.传递的是数组的首地址(也就是数组 第一个元素的地址)

    2.应该传递数组的长度

    C语言代码

    #include<stdio.h>
    #include<windows.h>
    
    void PrintArray(int arr[], int nLength)
    {
    	for(int i=0;i<nLength;i++)
    	{
    		printf("%d
    ",arr[i]);
    	}
    }
    
    void main()
    {
    	int arr[5] = {1,2,3,4,5};
    	PrintArray(arr,5);
    	
    	system("pause");
    	return ;
    } 
    

    汇编代码

    1:    #include<stdio.h>
    2:    #include<windows.h>
    3:
    4:    void PrintArray(int arr[], int nLength)
    5:    {
    00401020   push        ebp
    00401021   mov         ebp,esp
    00401023   sub         esp,44h
    00401026   push        ebx
    00401027   push        esi
    00401028   push        edi
    00401029   lea         edi,[ebp-44h]
    0040102C   mov         ecx,11h
    00401031   mov         eax,0CCCCCCCCh
    00401036   rep stos    dword ptr [edi]
    6:        for(int i=0;i<nLength;i++)
    00401038   mov         dword ptr [ebp-4],0
    0040103F   jmp         PrintArray+2Ah (0040104a)
    00401041   mov         eax,dword ptr [ebp-4]
    00401044   add         eax,1
    00401047   mov         dword ptr [ebp-4],eax
    0040104A   mov         ecx,dword ptr [ebp-4]
    0040104D   cmp         ecx,dword ptr [ebp+0Ch]
    00401050   jge         PrintArray+4Bh (0040106b)
    7:        {
    8:            printf("%d
    ",arr[i]);
    00401052   mov         edx,dword ptr [ebp-4]
    00401055   mov         eax,dword ptr [ebp+8]
    00401058   mov         ecx,dword ptr [eax+edx*4]
    0040105B   push        ecx
    0040105C   push        offset string "%d
    " (0042201c)
    00401061   call        printf (00401120)
    00401066   add         esp,8
    9:        }
    00401069   jmp         PrintArray+21h (00401041)
    10:   }
    0040106B   pop         edi
    0040106C   pop         esi
    0040106D   pop         ebx
    0040106E   add         esp,44h
    00401071   cmp         ebp,esp
    00401073   call        __chkesp (004011a0)
    00401078   mov         esp,ebp
    0040107A   pop         ebp
    0040107B   ret
    --- No source file  --------------------------------------------------------------------------------------------------------------------------------
    0040107C   int         3
    
    --- c:program filesmicrosoft visual studiomyprojects11	est.cpp  -------------------------------------------------------------------------------
    11:
    12:   void main()
    13:   {
    004010A0   push        ebp
    004010A1   mov         ebp,esp
    004010A3   sub         esp,54h
    004010A6   push        ebx
    004010A7   push        esi
    004010A8   push        edi
    004010A9   lea         edi,[ebp-54h]
    004010AC   mov         ecx,15h
    004010B1   mov         eax,0CCCCCCCCh
    004010B6   rep stos    dword ptr [edi]
    14:       int arr[5] = {1,2,3,4,5};
    004010B8   mov         dword ptr [ebp-14h],1
    004010BF   mov         dword ptr [ebp-10h],2
    004010C6   mov         dword ptr [ebp-0Ch],3
    004010CD   mov         dword ptr [ebp-8],4
    004010D4   mov         dword ptr [ebp-4],5
    15:       PrintArray(arr,5);
    004010DB   push        5
    004010DD   lea         eax,[ebp-14h]
    004010E0   push        eax
    004010E1   call        @ILT+0(PrintArray) (00401005)
    004010E6   add         esp,8
    16:
    17:       system("pause");
    004010E9   push        offset string "pause" (00422020)
    004010EE   call        system (004011e0)
    004010F3   add         esp,4
    18:       return ;
    19:   }
    004010F6   pop         edi
    004010F7   pop         esi
    004010F8   pop         ebx
    004010F9   add         esp,54h
    004010FC   cmp         ebp,esp
    004010FE   call        __chkesp (004011a0)
    00401103   mov         esp,ebp
    00401105   pop         ebp
    00401106   ret
    --- No source file  --------------------------------------------------------------------------------------------------------------------------------
    00401107   int         3
    
    

    2、用指针来操作数组

    数组作为参数时,传递的人是地址

    C语言代码

    #include<stdio.h>
    #include<windows.h>
    
    void PrintArray(int* p, int nLength)
    {
    	for(int i=0;i<nLength;i++)
    	{
    		printf("%d
    ",*(p+i));
    	}
    }
    
    void main()
    {
    	int arr[5] = {1,2,3,4,5};
    	PrintArray(&arr[0],5);
    	
    	system("pause");
    	return ;
    } 
    

    汇编代码

    1:    #include<stdio.h>
    2:    #include<windows.h>
    3:
    4:    void PrintArray(int* p, int nLength)
    5:    {
    00401020   push        ebp
    00401021   mov         ebp,esp
    00401023   sub         esp,44h
    00401026   push        ebx
    00401027   push        esi
    00401028   push        edi
    00401029   lea         edi,[ebp-44h]
    0040102C   mov         ecx,11h
    00401031   mov         eax,0CCCCCCCCh
    00401036   rep stos    dword ptr [edi]
    6:        for(int i=0;i<nLength;i++)
    00401038   mov         dword ptr [ebp-4],0
    0040103F   jmp         PrintArray+2Ah (0040104a)
    00401041   mov         eax,dword ptr [ebp-4]
    00401044   add         eax,1
    00401047   mov         dword ptr [ebp-4],eax
    0040104A   mov         ecx,dword ptr [ebp-4]
    0040104D   cmp         ecx,dword ptr [ebp+0Ch]
    00401050   jge         PrintArray+4Bh (0040106b)
    7:        {
    8:            printf("%d
    ",*(p+i));
    00401052   mov         edx,dword ptr [ebp-4]
    00401055   mov         eax,dword ptr [ebp+8]
    00401058   mov         ecx,dword ptr [eax+edx*4]
    0040105B   push        ecx
    0040105C   push        offset string "%d
    " (0042201c)
    00401061   call        printf (00401120)
    00401066   add         esp,8
    9:        }
    00401069   jmp         PrintArray+21h (00401041)
    10:   }
    0040106B   pop         edi
    0040106C   pop         esi
    0040106D   pop         ebx
    0040106E   add         esp,44h
    00401071   cmp         ebp,esp
    00401073   call        __chkesp (004011a0)
    00401078   mov         esp,ebp
    0040107A   pop         ebp
    0040107B   ret
    --- No source file  --------------------------------------------------------------------------------------------------------------------------------
    0040107C   int         3
    --- C:Program FilesMicrosoft Visual StudioMyProjects11	est.cpp  -------------------------------------------------------------------------------
    11:
    12:   void main()
    13:   {
    004010A0   push        ebp
    004010A1   mov         ebp,esp
    004010A3   sub         esp,54h
    004010A6   push        ebx
    004010A7   push        esi
    004010A8   push        edi
    004010A9   lea         edi,[ebp-54h]
    004010AC   mov         ecx,15h
    004010B1   mov         eax,0CCCCCCCCh
    004010B6   rep stos    dword ptr [edi]
    14:       int arr[5] = {1,2,3,4,5};
    004010B8   mov         dword ptr [ebp-14h],1
    004010BF   mov         dword ptr [ebp-10h],2
    004010C6   mov         dword ptr [ebp-0Ch],3
    004010CD   mov         dword ptr [ebp-8],4
    004010D4   mov         dword ptr [ebp-4],5
    15:       PrintArray(&arr[0],5);
    004010DB   push        5
    004010DD   lea         eax,[ebp-14h]
    004010E0   push        eax
    004010E1   call        @ILT+10(PrintArray) (0040100f)
    004010E6   add         esp,8
    16:
    17:       system("pause");
    004010E9   push        offset string "pause" (00422020)
    004010EE   call        system (004011e0)
    004010F3   add         esp,4
    18:       return ;
    19:   }
    004010F6   pop         edi
    004010F7   pop         esi
    004010F8   pop         ebx
    004010F9   add         esp,54h
    004010FC   cmp         ebp,esp
    004010FE   call        __chkesp (004011a0)
    00401103   mov         esp,ebp
    00401105   pop         ebp
    00401106   ret
    --- No source file  --------------------------------------------------------------------------------------------------------------------------------
    00401107   int         3
    
    

    2.17.指针与字符串

    1、字符串的几种表示方式有什么区别?

    char str[6] = {'A','B','C','D',E','0'};	//结尾要 'O'或者0
    char str[] = "ABCDE", 	//编译器末尾填0
    char* str= "ABCDE";		//常量区
    
    //打印
    print("%s
    " ,str);
    

    2、常用的字符串函数

    1、int strlen (char* s)
    返回值是字符串s的长度。不包括结束符'/0'。
    
    2、char* strcpy (char* dest, char* src);
    复制字符串src到dest中。返回指针为dest的值。
    
    3、char* strcat (char* dest, char* src);
    将字符串src添加到dest尾部。返回指针为dest的值。
    
    4、int strcmp ( char* s1, char* s2);
    一样返回0 不一样返回非0
    

    2.18.指针取值的两种方式

    1、一级指针和多级指针

    c语言代码

    #include<stdio.h>
    #include<windows.h>
    
    void main()
    {
    	int i = 100;
    
    	int* p1 = &i;
    	int** p2 = &p1;
    	int*** p3 = &p2;
    	int**** p4 = &p3;
    	int***** p5 = &p4;
    	int****** p6 = &p5;
    	int******* p7 = &p6;
    
    	int y = *******p7;  //y=1
    
    	int z= p7[0][0][0][0][0][0][0]; //z=1 
    
    	
    	system("pause");
    	return ;
    } 
    

    汇编代码

    1:    #include<stdio.h>
    2:    #include<windows.h>
    3:
    4:    void main()
    5:    {
    00401010   push        ebp
    00401011   mov         ebp,esp
    00401013   sub         esp,68h
    00401016   push        ebx
    00401017   push        esi
    00401018   push        edi
    00401019   lea         edi,[ebp-68h]
    0040101C   mov         ecx,1Ah
    00401021   mov         eax,0CCCCCCCCh
    00401026   rep stos    dword ptr [edi]
    6:        int i = 100;
    00401028   mov         dword ptr [ebp-4],64h
    7:
    8:        int* p1 = &i;
    0040102F   lea         eax,[ebp-4]
    00401032   mov         dword ptr [ebp-8],eax
    9:        int** p2 = &p1;
    00401035   lea         ecx,[ebp-8]
    00401038   mov         dword ptr [ebp-0Ch],ecx
    10:       int*** p3 = &p2;
    0040103B   lea         edx,[ebp-0Ch]
    0040103E   mov         dword ptr [ebp-10h],edx
    11:       int**** p4 = &p3;
    00401041   lea         eax,[ebp-10h]
    00401044   mov         dword ptr [ebp-14h],eax
    12:       int***** p5 = &p4;
    00401047   lea         ecx,[ebp-14h]
    0040104A   mov         dword ptr [ebp-18h],ecx
    13:       int****** p6 = &p5;
    0040104D   lea         edx,[ebp-18h]
    00401050   mov         dword ptr [ebp-1Ch],edx
    14:       int******* p7 = &p6;
    00401053   lea         eax,[ebp-1Ch]
    00401056   mov         dword ptr [ebp-20h],eax
    15:
    16:       int y = *******p7;  //y=1
    00401059   mov         ecx,dword ptr [ebp-20h]
    0040105C   mov         edx,dword ptr [ecx]
    0040105E   mov         eax,dword ptr [edx]
    00401060   mov         ecx,dword ptr [eax]
    00401062   mov         edx,dword ptr [ecx]
    00401064   mov         eax,dword ptr [edx]
    00401066   mov         ecx,dword ptr [eax]
    00401068   mov         edx,dword ptr [ecx]
    0040106A   mov         dword ptr [ebp-24h],edx
    17:
    18:       int z= p7[0][0][0][0][0][0][0]; //z=1
    0040106D   mov         eax,dword ptr [ebp-20h]
    00401070   mov         ecx,dword ptr [eax]
    00401072   mov         edx,dword ptr [ecx]
    00401074   mov         eax,dword ptr [edx]
    00401076   mov         ecx,dword ptr [eax]
    00401078   mov         edx,dword ptr [ecx]
    0040107A   mov         eax,dword ptr [edx]
    0040107C   mov         ecx,dword ptr [eax]
    0040107E   mov         dword ptr [ebp-28h],ecx
    19:
    20:
    21:       system("pause");
    00401081   push        offset string "pause" (0042201c)
    00401086   call        system (004010d0)
    0040108B   add         esp,4
    22:       return ;
    23:   }
    0040108E   pop         edi
    0040108F   pop         esi
    00401090   pop         ebx
    00401091   add         esp,68h
    00401094   cmp         ebp,esp
    00401096   call        __chkesp (004011e0)
    0040109B   mov         esp,ebp
    0040109D   pop         ebp
    0040109E   ret
    --- No source file  --------------------------------------------------------------------------------------------------------------------------------
    0040109F   int         3
    

    2、总结:

    *(p+i)= p[i]
    *(*(p+i)+k) = p[i][k]
    *(*(*(p+i)+k)+m) = p[i][k][m]
    (*(p+i)+k)+m)+W)+t) = p[jIk]Im][W[t]
    
    *()与[]可以相互转换
    

    2.19.结构体指针

    通过结构体指针读取和修改值

    #include<stdio.h>
    #include<stdlib.h>
    #include<windows.h>
    
    Point{
    	int x;
    	int y;
    }
    
    void main()
    {
    	Point p = {1,2};
    
    	Point* px = &p;
    	
    	int x = px->x;        //x=1
    	px->y =100;
    	int u = px->y;		  //y=100
    
    	system("pause");
    	return ;
    } 
    
    

    2.20.指针数组和数组指针

    1、指针数组的定义

    char arr[10];   	 //10 char
    char* arr[10];		 //10 指针(char*)	 每个成员4字节
    Point* arr[10];		 //10 指针(Point*) 每个成员4字节
    int******* arr[10];	  // //10 指针(int*******) 每个成员4字节
    

    2、指针数组的赋值

    char* a = "hello";  //a存的是地址,里面存放的值是 “hello”
    char* b = "你好";
    
    //汇编代码
    7:        char* a = "hello";
    00401028   mov         dword ptr [ebp-4],offset string "hello" (004230cc)
    8:        char* b = "你好";
    0040102F   mov         dword ptr [ebp-8],offset string "xc4xe3xbaxc3" (004230c4)
    
    char* arr1[2] = {a,b};    //存放两个地址a和b
    
    char* arr2[2] = {"hello","你好"};   //存放的也是两个地址
        
    //汇编代码
    7:        char* a = "hello";
    00401028   mov         dword ptr [ebp-4],offset string "hello" (0042202c)
    8:        char* b = "你好";
    0040102F   mov         dword ptr [ebp-8],offset string "xc4xe3xbaxc3" (00422024)
    9:
    10:       char* arr1[2] = {a,b};
    00401036   mov         eax,dword ptr [ebp-4]
    00401039   mov         dword ptr [ebp-10h],eax
    0040103C   mov         ecx,dword ptr [ebp-8]
    0040103F   mov         dword ptr [ebp-0Ch],ecx
    11:       char* arr2[2] = {"hello","你好"};
    00401042   mov         dword ptr [ebp-18h],offset string "hello" (0042202c)
    00401049   mov         dword ptr [ebp-14h],offset string "xc4xe3xbaxc3" (00422024)
    

    3、结构体指针数组

    struct Point
    {
        int x;
        int y;
    };
    
    Point p;	//8字节
    Point arr[10];	//8x10字节
    Point* arrPoint[10;	//4x10字节
    

    4、数组指针的定义

    int(*px)[5];
    char(*px)[5];	//一维数组指针
    
    int(*px)[5][4];	//二维数组指针
    

    5、数组指针的宽度与赋值

    int(*px1) [5];	//一维数组指针
    char(*px2) [3];
    int(*px3) [2][2];	//二维数组指针
    char(*px4) [3][3][3);	//三维数组指针
    print("%d %d %d %d 
    " ,sizeof(px1),sizeof(px2),sizeof(px3),sizeof(px4));   //4 4 4 4
                      
    px1 = (int (*)[5])1;
    px2 = (char (*)[(3])2;
    px3 = (int (*)[2][2])3;
    px4 = (char (*)[3][3][3])4;
    
    

    6、数组指针的使用

    #include<stdio.h>
    #include<stdlib.h>
    #include<windows.h>
    
    void main()
    {
    	int arr[] = {1,2,3,4,5,6,7,8,9,0};
    
    	int(*px)[10] = &arr;
    
    	printf("%d
    ",(*px)[0]);	// 1
    
    	system("pause");
    	return ;
    } 
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<windows.h>
    
    void main()
    {
    	int arr[3][3] = 
    	{
    		{1,2,3},
    		{4,5,6},
    		{7,8,9}
    	};
    	
    	int(*px)[3] = &arr[0];
    
    	printf("%d %d
    ",(*px)[0],(*px)[2]);    //1  3
    
    	px++;
    
    	printf("%d %d
    ",(*px)[0],(*px)[2]);	//4  6
    
    	system("pause");
    	return ;
    } 
    

    2.21.常见的几种调用约定:

    三种常见调用约定

    调用约定			参数压栈顺序			  平衡堆栈
    cdecl			   从右至左入栈		   调用者清理栈
    
    stdcall			   从右至左入栈		   自身清理堆栈
    
    _ _fastcall     ECX/EDX传送前两个          自身清理堆栈
                    剩下:从右至左入栈
    

    2.22.函数指针

    1、函数指针类型变量的定义
    函数指针变量定义的格式:

    返回类型(调用约定 *变量名)(参数列表);
    如:
    int ( _cdecl *pFun)(int,int);
    

    2、通过函数指针绕过断点

    <1>函数指针变量的定义
    int (__stdcall *pFun)(int,int,int,int,int);
    
    <2>正常调用
    MessaleBox(0,0,0,0);
    
    <3>通过函数指针绕过断点
    pFun = (int (__stdcall *)(int,int,int,int,int))0x77D5055C;
    pFun(0,0,0,0,0);
    

    2.23.预处理之宏定义

    1、什么是预处理:
    预处理一般是指在程序源代码被转换为二进制代码之前,由预处理器对程序源代码文本进行处理处理后的结再由编译器进- -步编译。
    预处理功能主要包括宏定义,文件包含,条件编译三部分

    2、宏定义

    <1>简单宏: #define 标识符字符序列
    # define FALSE 0
    # define NAME "测试"
    # define_ IN
    # define__ OUT
    
    <2>带参数的宏: #define 标识符(参数表)字符序列
    #define MAX(A,B) ((A)> (B)?(A):(B))
    

    注意事项:
    1、只作字符序列的替换工作,不作任何语法的检查,在编译前处理。
    2、宏名标识符与左圆括号之间不允许有空白符,应紧接在- -起。
    3、为了避免出错,宏定义中给形参加上括号。
    4、多行声明时,回车换行前要加上字符‘’,即“[enter]" ,注意字符
    ‘’ 后要紧跟回车键,中间不能有空格或其他字符。
    5、末尾不需要分号。

    2.24.条件编译与文件包含

    1、什么是条件编译?

    #if 0
    	printf("------")
    #endif        
    

    2、预处理指令:条件编译是通过预处理指令实现的
    image
    3、文件包含有两种格式
    分别是: #include "file"和#include
    1.使用双引号,系统首先到当前目录下查找被包含的文件,如果没找到,再到系
    统指定的"包含文件目录" (由用户在配置环境时设置)去找。
    2.使用尖括号:直接到系统指定的"包含文件目录"去查找。
    总结:
    系统文件用<>
    自己定义的文件用””

    4、如何解决重复包含问题

    • 条件编译
    • 前置声明
    作者:zhang_derek

    个性签名:其实人跟树一样,越是向往高处的阳光,它的根就越要伸向黑暗的地底。

  • 相关阅读:
    zedGraph画心电图
    多窗体之间进行数据通信 传值
    C#共有五种访问修饰符:public、private、protected、internal、protected internal。作用范围如下表:
    Linux进程调度与切换
    Linux学习总结
    Linux内核如何启动并装载一个可执行程序
    Linux编写Shell脚本入门
    如何使用委托
    深入剖析反射
    浅析C#中的文件操作
  • 原文地址:https://www.cnblogs.com/derek1184405959/p/14636602.html
Copyright © 2020-2023  润新知