什么是函数?
通俗易懂的说,函数就是一个代码块,由若干的功能构成,具有可以传递参数和返回值的代码块,无论是为了代码的美观,还是为了代码的重复利用,都需要写函数
在我们还没有学习函数之前,我们的代码:
int main()
{
int x = 10;
int y = 20;
int z = 30;
int a, b, c, d;
a = x * y;
b = y * z;
c = z * x;
d = a + b + c;
}
在main函数里大量编写代码
这样既不美观也不方便,我们就需要定义一个函数
怎么定义函数:
int fun1( int x, int y)
参数返回类型 函数名 形参1 形参2
{
int z;
定义局部变量
z=x+y;
局部变量等于形参1+形参2
return z;
返回计算完的结果
}
我们可以定义一个返回两个数相加的函数
int fun1(int x, int y)
{
return x + y;
}
如果我们需要多次使用这个代码
fun1(1,3); //4
fun1(2,4); //6
一个加法的函数我们使用了两次,以后使用的时候只需要调用即可
当我们写一个函数的时候:我们得到的函数名其实只是一个地址
fun1(1, 3);
00823CD8 push 3
00823CDA push 1
00823CDC call fun1 (08213A2h)
00823CE1 add esp,8
在正向程序猿的眼里,我们创建了一个加法函数,我们有函数名
在我们眼里,我们通过汇编分析:
c++默认使用__cdcall,并且这个函数是外平栈(外部平衡堆栈)
我们CALL的时候,其实CALL的是0x08213A2,函数名是为了方便我们使用
int fun1(int x, int y)
{
00821780 push ebp
00821781 mov ebp,esp
00821783 sub esp,0C0h
00821789 push ebx
0082178A push esi
0082178B push edi
0082178C lea edi,[ebp-0C0h]
00821792 mov ecx,30h
00821797 mov eax,0CCCCCCCCh
0082179C rep stos dword ptr es:[edi]
0082179E mov ecx,offset _0340B6FD_consoleapplication3.cpp (082C008h)
008217A3 call @__CheckForDebuggerJustMyCode@4 (0821208h)
printf("%x\n", x + y);
008217A8 mov eax,dword ptr [x]
008217AB add eax,dword ptr [y]
008217AE push eax
008217AF push offset string "%x\n" (0827BCCh)
008217B4 call _printf (082138Eh)
008217B9 add esp,8
return 0;
008217BC xor eax,eax
}
这才是我们真正的代码
push参数压栈,
push返回值,修改eip
call 0x08213A2h
保存寄存器,提升堆栈,填充缓冲区
调用打印函数,降低堆栈,还原寄存器
平衡堆栈