C语言再学习2-定义函数

什么是函数?

通俗易懂的说,函数就是一个代码块,由若干的功能构成,具有可以传递参数和返回值的代码块,无论是为了代码的美观,还是为了代码的重复利用,都需要写函数
在我们还没有学习函数之前,我们的代码:

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

保存寄存器,提升堆栈,填充缓冲区
调用打印函数,降低堆栈,还原寄存器
平衡堆栈

c语言的函数其实就是一个个的汇编堆栈!

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_35425243/article/details/82771907