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 Files\Microsoft Visual Studio\MyProjects\11\test.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;
}



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 Files\Microsoft Visual Studio\MyProjects\11\test.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\n",x);
} return;
}



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 Files\Microsoft Visual Studio\MyProjects\11\test.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

堆栈图



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

堆栈图

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

5、有符号与无符号数(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("+++++\n");
}
else
{
printf("------\n");
} 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("+++++\n");
0040103E push offset string "+++++\n" (00420028)
00401043 call printf (00401090)
00401048 add esp,4
12: }
13: else
0040104B jmp main+4Ah (0040105a)
14: {
15: printf("------\n");
0040104D push offset string "------\n" (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\n");
break;
case 2:
printf("B\n");
break;
case 3:
printf("C\n");
break;
case 4:
printf("D\n");
break;
case 5:
printf("E\n");
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\n");
00401057 push offset string "A\n" (0042002c)
0040105C call printf (00401130)
00401061 add esp,4
10: break;
00401064 jmp $L42195+0Dh (004010a0)
11: case 2:
12: printf("B\n");
00401066 push offset string "B\n" (00420028)
0040106B call printf (00401130)
00401070 add esp,4
13: break;
00401073 jmp $L42195+0Dh (004010a0)
14: case 3:
15: printf("C\n");
00401075 push offset string "C\n" (00420024)
0040107A call printf (00401130)
0040107F add esp,4
16: break;
00401082 jmp $L42195+0Dh (004010a0)
17: case 4:
18: printf("D\n");
00401084 push offset string "D\n" (00420020)
00401089 call printf (00401130)
0040108E add esp,4
19: break;
00401091 jmp $L42195+0Dh (004010a0)
20: case 5:
21: printf("E\n");
00401093 push offset string "E\n" (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\n");
break;
case 2:
printf("B\n");
break;
case 4:
printf("C\n");
break;
case 7:
printf("D\n");
break;
case 8:
printf("E\n");
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\n");
00401057 push offset string "A\n" (0042002c)
0040105C call printf (00401130)
00401061 add esp,4
10: break;
00401064 jmp $L42196+0Dh (004010a0)
11: case 2:
12: printf("B\n");
00401066 push offset string "B\n" (00420028)
0040106B call printf (00401130)
00401070 add esp,4
13: break;
00401073 jmp $L42196+0Dh (004010a0)
14: case 4:
15: printf("C\n");
00401075 push offset string "C\n" (00420024)
0040107A call printf (00401130)
0040107F add esp,4
16: break;
00401082 jmp $L42196+0Dh (004010a0)
17: case 7:
18: printf("D\n");
00401084 push offset string "D\n" (00420020)
00401089 call printf (00401130)
0040108E add esp,4
19: break;
00401091 jmp $L42196+0Dh (004010a0)
20: case 8:
21: printf("E\n");
00401093 push offset string "E\n" (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的地址,

2.8.for循环

C语言代码

#include<stdio.h>
#include<windows.h> void Myprint()
{
int i;
for(i=0;i<10;i++)
{
printf("%d\n",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\n",i);
00401050 mov ecx,dword ptr [ebp-4]
00401053 push ecx
00401054 push offset string "E\n" (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\n%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\n%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\n%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\n",sizeof(test1)); //8
printf("%d\n",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的整数倍

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\n",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\n",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\n",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\n",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\n"); //1
}
else
{
printf("2\n");
} 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\n",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\n",r);
00401054 mov ecx,dword ptr [ebp-4]
00401057 push ecx
00401058 push offset string "%d\n" (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\n",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\n",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\n" (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 files\microsoft visual studio\myprojects\11\test.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\n",*(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\n",*(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\n" (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 Files\Microsoft Visual Studio\MyProjects\11\test.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\n" ,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 "\xc4\xe3\xba\xc3" (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 "\xc4\xe3\xba\xc3" (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 "\xc4\xe3\xba\xc3" (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 \n" ,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\n",(*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\n",(*px)[0],(*px)[2]); //1 3 px++; printf("%d %d\n",(*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、预处理指令:条件编译是通过预处理指令实现的



3、文件包含有两种格式

分别是: #include "file"和#include

1.使用双引号,系统首先到当前目录下查找被包含的文件,如果没找到,再到系

统指定的"包含文件目录" (由用户在配置环境时设置)去找。

2.使用尖括号:直接到系统指定的"包含文件目录"去查找。

总结:

系统文件用<>

自己定义的文件用””

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

  • 条件编译
  • 前置声明

滴水逆向初级-C语言(二)的更多相关文章

  1. 【Linux】-NO.87.Assembly.1.滴水逆向.1.001-【介绍】-

    1.0.0 Summary Tittle:[Linux]-NO.87.Assembly.1.滴水逆向.1.001-[基础]- Style:Java Series:Log4j Since:2017-04 ...

  2. c语言二维数组传递

    c语言二维数组传递,目前我总结三种方法,以及纠正一个不能使用的方法 /********************************* * 方法1: 第一维的长度可以不指定 * * 但必须指定第二维 ...

  3. Coding 初级教程(二)——上传已有项目

    Coding 初级教程(二)——上传已有项目 [摘要:方针读者 :已具有 Coding.net 的账号. 本文首要先容若何把项目上传到 Coding.net 上. 分两种环境,一种是项目已归入到 gi ...

  4. 【Assembly】-NO.88.Assembly.2.滴水逆向.1.002-【位运算及基础指令】-

    1.0.0 Summary Tittle:[Assembly]-NO.88.Assembly.2.滴水逆向.1.002-[]- Style:Java Series:Log4j Since:2018-0 ...

  5. SpringCloud实战之初级入门(二)— 服务注册与服务调用

    目录 1.环境介绍 2.服务提供 2.1 创建工程 2.2 修改配置文件 2.3 修改启动文件 2.5 亲测注意事项 3.服务调用 3.1 创建工程 3.2 修改配置文件 3.3 修改启动文件 3.4 ...

  6. Kotlin——初级篇(二):变量、常量、注释

    在Kotlin中的变量.常量以及注释多多少少和Java语言是有着不同之处的.不管是变量.常量的定义方式,还是注释的使用.下面详细的介绍Kotlin中的变量.常量.注释的使用.以及和Java的对比. 如 ...

  7. 关于c语言二维数组与指针的个人理解及处理办法。

    相信大家在学习C语言时,对一维数组和指针的理解应该是自信的,但是,我在学习过程中,看到网上一些博文,发现即便是参加工作的一些专业编程人员,突然碰到二维数组和指针的问题时,也可能会遇到难以处理的诡异问题 ...

  8. C语言 二维数组复制、清零及打印显示

    #include <stdlib.h> #include <stdio.h> #include <string.h> //二维整型数组打印显示 ],int row, ...

  9. C语言二维数组作业

    一.PTA实验作业 题目1:7-3 出生年 1. 本题PTA提交列表 2. 设计思路 1.声明一个函数different()用来计算一个年份的不同数字个数 2.定义y(y是来计算符合要求的年份的量), ...

随机推荐

  1. tree ignore & bash & cmd

    tree ignore & bash & cmd tree ignore https://unix.stackexchange.com/a/47806 https://zaiste.n ...

  2. HTTP/2 & Push Cache

    HTTP/2 & Push Cache HTTP/2 & 推送缓存 https://caniuse.com/#search=http2 https://jakearchibald.co ...

  3. sketch 导出 svg

    sketch 导出 svg refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  4. Mac Benchmarks

    Mac Benchmarks https://browser.geekbench.com/mac-benchmarks https://www.geekbench.com/ https://www.f ...

  5. qt 取进程列表,读写内存, 写字节集

    导入库 pro win32:LIBS += -lpsapi win32:LIBS += -lkernel32 获取列表 #include "mainwindow.h" #inclu ...

  6. NGK Global首尔站:内存是未来获取数字财富的新模式

    近日,NGK路演在NGK韩国社区的积极举办下顺利落下帷幕.此次路演在首尔举行,在活动当天,NGK的核心团队成员.行业专家.投资银行精英.生态产业代表和数百名NGK韩国社区粉丝一起参加NGK Globa ...

  7. C语言数据类型思维导图

  8. Vue为何采用异步渲染

    Vue为何采用异步渲染 Vue在更新DOM时是异步执行的,只要侦听到数据变化,Vue将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更,如果同一个watcher被多次触发,只会被推入到队列中一次 ...

  9. PythonPEP8 风格规范指南

    PEP是Python Enhancement Proposal的缩写,通常翻译为"Python增强提案".每个PEP都是一份为Python社区提供的指导Python往更好的方向发展 ...

  10. EF获取数据库表名和列名

    EF获取数据库表名和列名 新建 模板 小书匠 /// <summary>  /// 通过当前DBContext上下文获取对应数据库中所有得表  /// </summary>  ...