页面网站建设牛商网做网站要多少钱
web/
2025/9/27 16:17:49/
文章来源:
页面网站建设,牛商网做网站要多少钱,网站建设辶金手指谷哥十四,数据标签wordpress环境#xff1a;VC
作用#xff1a; 函数是完成特定任务的独立程序代码单元
1、创建和使用函数
函数原型#xff1a;声明函数是什么类型#xff0c;指明函数的返回值和函数接收的参数类型#xff0c;函数和变量一样#xff0c;有多种类型#xff0c;任何程序在使用函…环境VC
作用 函数是完成特定任务的独立程序代码单元
1、创建和使用函数
函数原型声明函数是什么类型指明函数的返回值和函数接收的参数类型函数和变量一样有多种类型任何程序在使用函数之前都要声明该函数的类型函数调用表明在此处执行函数执行到函数调用的语句时程序会找到该函数的定义并执行其中的内容执行完返回调用函数继续执行下一行函数定义详细说明函数要干啥
#include stdio.hint add(int a,int b); //函数原型int main(void)
{int a1,b1,sum0;sumadd(a,b); //函数调用printf(sum%d\n,sum);return 0;
}//函数定义
int add(int a,int b)
{return ab;
}我们看看反汇编 函数原型 我们可以看出函数原型这里没有生成机器码这个是给编译器看得告诉编译器这个函数的返回值和函数接收的参数类型并在别处查看该函数类型机器码是给CPU执行的所以CPU执行到这里不会干任何事情 函数调用
8: sumadd(a,b); //函数调用
0040104D 8B 45 F8 mov eax,dword ptr [ebp-8]
00401050 50 push eax
00401051 8B 4D FC mov ecx,dword ptr [ebp-4]
00401054 51 push ecx
00401055 E8 AB FF FF FF call ILT0(add) (00401005)
0040105A 83 C4 08 add esp,8
0040105D 89 45 F4 mov dword ptr [ebp-0Ch],eax函数调用之前我们可以看到会先把参数存放到栈里面也就是ab的值然后到00401005地址执行这个地址有个jmp语句会跳转到函数的定义出执行 函数定义
13: //函数定义
14: int add(int a,int b)
15: {
004010A0 55 push ebp
004010A1 8B EC mov ebp,esp
004010A3 83 EC 40 sub esp,40h
004010A6 53 push ebx
004010A7 56 push esi
004010A8 57 push edi
004010A9 8D 7D C0 lea edi,[ebp-40h]
004010AC B9 10 00 00 00 mov ecx,10h
004010B1 B8 CC CC CC CC mov eax,0CCCCCCCCh
004010B6 F3 AB rep stos dword ptr [edi]
16: return ab;
004010B8 8B 45 08 mov eax,dword ptr [ebp8]
004010BB 03 45 0C add eax,dword ptr [ebp0Ch]
17: }
004010BE 5F pop edi
004010BF 5E pop esi
004010C0 5B pop ebx
004010C1 8B E5 mov esp,ebp
004010C3 5D pop ebp
004010C4 C3 ret从上面的程序我们可以看出函数定义会先把esp存放到栈里面然后把esp的值给ebp接着开辟一个40h的栈然后把ebx、 esi、 edi存放到栈里面接着在一些连续地址存放0CCCCCCCCh把这些做好后再执行函数定义里的语句。
16: return ab;
004010B8 8B 45 08 mov eax,dword ptr [ebp8]
004010BB 03 45 0C add eax,dword ptr [ebp0Ch]我们看看函数的最后
004010BE 5F pop edi
004010BF 5E pop esi
004010C0 5B pop ebx
004010C1 8B E5 mov esp,ebp
004010C3 5D pop ebp
004010C4 C3 ret函数的最后把函数开始存放这些寄存器的内容又给了他们ebp的值给espebp恢复函数之前的ebp接着返回。与函数调用的作用是一样的
函数的作用只完成特定任务其他什么都没变从函数调用到函数定义最后返回看起来是只对了a和b的值进行了操作其他啥都没变
总结 函数原型没有生成机器码告诉编译器我的参数是那些和返回值是那些函数调用会把参数先压入栈接着执行call到一个地址执行这个地址有一个jmp命令会到函数定义出执行函数定义会先把一些寄存器先压入栈然后给一些内存赋值在最后又会把这些寄存器给弹出恢复成原值执行ret命令返回调用函数继续执行下一行。
2、传值和传址的区别
首先我们要认识几个小知识
运算符取变量的存储地址*间接运算符取存储在指针指向地址上的值也可以用来声明指针声明指针变量类型 * 变量名声明指针变量必须指定指针所指向变量的类型因为不同变量类型占用不同的存储空间
#include stdio.hint add1(int a,int b); //函数原型
int add2(int *a,int *b); //函数原型
int main(void)
{int a1,b1,sum1,sum2;sum1add1(a,b); //函数调用printf(sum1%d\n,sum1);sum2add2(a,b); //函数调用printf(sum2%d\n,sum2);return 0;
}//函数定义
int add1(int a,int b)
{return ab;
}int add2(int *a,int *b)
{return *a*b;
}传值
8: sum1add1(a,b); //函数调用
0040D786 8B 45 F8 mov eax,dword ptr [ebp-8]
0040D789 50 push eax
0040D78A 8B 4D FC mov ecx,dword ptr [ebp-4]
0040D78D 51 push ecx
0040D78E E8 7C 38 FF FF call ILT10(add) (0040100f)
0040D793 83 C4 08 add esp,8
0040D796 89 45 F4 mov dword ptr [ebp-0Ch],eax值传给eax寄存器然后入栈
传址
10: sum2add2(a,b); //函数调用
0040D7AA 8D 45 F8 lea eax,[ebp-8]
0040D7AD 50 push eax
0040D7AE 8D 4D FC lea ecx,[ebp-4]
0040D7B1 51 push ecx
0040D7B2 E8 5D 38 FF FF call ILT15(add2) (00401014)
0040D7B7 83 C4 08 add esp,8
0040D7BA 89 45 F0 mov dword ptr [ebp-10h],eax把地址传给eax然后入栈 我们知道传值不可以修改变量的值而传址却可以从汇编角度看我们可以更加的清晰明白传值只是将值传过去了函数调用是去函数定义处执行不知道变量在哪里所以没办法修改传地址到函数定义时就知道变量的地址在哪里了所以能修改变量得内容
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/80980.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!