c和汇编---函数

环境:VC++

作用:
函数是完成特定任务的独立程序代码单元

1、创建和使用函数

  • 函数原型:声明函数是什么类型,指明函数的返回值和函数接收的参数类型,函数和变量一样,有多种类型,任何程序在使用函数之前都要声明该函数的类型
  • 函数调用:表明在此处执行函数,执行到函数调用的语句时,程序会找到该函数的定义并执行其中的内容,执行完返回调用函数继续执行下一行
  • 函数定义:详细说明函数要干啥
#include "stdio.h"int add(int a,int b);	//函数原型int main(void)
{int a=1,b=1,sum=0;sum=add(a,b);		//函数调用printf("sum=%d\n",sum);return 0;
}//函数定义
int add(int a,int b)
{return a+b;
}

我们看看反汇编:
函数原型:
在这里插入图片描述
我们可以看出,函数原型这里没有生成机器码,这个是给编译器看得,告诉编译器这个函数的返回值和函数接收的参数类型,并在别处查看该函数类型,机器码是给CPU执行的,所以CPU执行到这里,不会干任何事情
函数调用:

8:        sum=add(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        @ILT+0(add) (00401005)
0040105A 83 C4 08             add         esp,8
0040105D 89 45 F4             mov         dword ptr [ebp-0Ch],eax

函数调用之前,我们可以看到会先把参数存放到栈里面,也就是a,b的值,然后到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 a+b;
004010B8 8B 45 08             mov         eax,dword ptr [ebp+8]
004010BB 03 45 0C             add         eax,dword ptr [ebp+0Ch]
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 a+b;
004010B8 8B 45 08             mov         eax,dword ptr [ebp+8]
004010BB 03 45 0C             add         eax,dword ptr [ebp+0Ch]

我们看看函数的最后

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的值给esp,ebp恢复函数之前的ebp,接着返回。与函数调用的作用是一样的

函数的作用只完成特定任务,其他什么都没变,从函数调用到函数定义,最后返回,看起来是只对了a和b的值进行了操作,其他啥都没变

总结:
函数原型没有生成机器码,告诉编译器我的参数是那些和返回值是那些,函数调用会把参数先压入栈,接着执行call到一个地址执行,这个地址有一个jmp命令,会到函数定义出执行,函数定义会先把一些寄存器先压入栈,然后给一些内存赋值,在最后又会把这些寄存器给弹出,恢复成原值,执行ret命令,返回调用函数继续执行下一行。

2、传值和传址的区别

首先我们要认识几个小知识

  • &运算符:取变量的存储地址
  • *间接运算符:取存储在指针指向地址上的值,也可以用来声明指针
  • 声明指针变量:类型 * 变量名,声明指针变量必须指定指针所指向变量的类型,因为不同变量类型占用不同的存储空间
#include "stdio.h"int add1(int a,int b);	//函数原型
int add2(int *a,int *b);	//函数原型
int main(void)
{int a=1,b=1,sum1,sum2;sum1=add1(a,b);		//函数调用printf("sum1=%d\n",sum1);sum2=add2(&a,&b);		//函数调用printf("sum2=%d\n",sum2);return 0;
}//函数定义
int add1(int a,int b)
{return a+b;
}int add2(int *a,int *b)
{return *a+*b;
}

传值:

8:        sum1=add1(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        @ILT+10(add) (0040100f)
0040D793 83 C4 08             add         esp,8
0040D796 89 45 F4             mov         dword ptr [ebp-0Ch],eax

值传给eax寄存器,然后入栈

传址:

10:       sum2=add2(&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        @ILT+15(add2) (00401014)
0040D7B7 83 C4 08             add         esp,8
0040D7BA 89 45 F0             mov         dword ptr [ebp-10h],eax

把地址传给eax,然后入栈
我们知道传值不可以修改变量的值,而传址却可以,从汇编角度看,我们可以更加的清晰明白,传值只是将值传过去了,函数调用是去函数定义处执行,不知道变量在哪里,所以没办法修改,传地址到函数定义时就知道变量的地址在哪里了,所以能修改变量得内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/380355.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ajax_ASP.NET 添加 Ajax 和客户端功能_01

现在,基于不同开发思想的前端 Ajax 框架越来越多,功能越来越强大,UI 越来越炫,但随之复杂度也越来越高,尤其是UI做得漂亮的,比如 Ext.Net。 可是无论框架多么复杂,思想都一样的。因为&#xff0…

计算机常用英语1000个,1000个常用英语单词.pdf

[键入文字 ]常用英语单词 2000 个One 16 as [ ?z, ? z] ad. 同样地 prep. 当作conj. 随着 ; 因为1 the [e?, ei: ] art. 这,那 ad.[ 用于比17 not [n?t] ad. 不,没,不是较级;最高级前 ]18 on [?n] prep. 在 …上;…

三角形面积

描述 给你三个点,表示一个三角形的三个顶点,现你的任务是求出该三角形的面积 输入 每行是一组测试数据,有6个整数x1,y1,x2,y2,x3,y3分别表示三个点的横纵坐标。(坐标值都在0到10000之间) 输入0 0 0 0 0 0表示输入结…

python投骰子程序代码_用于双骰子(一个偏向一个法线)仿真的Python程序

python投骰子程序代码Here, we will be simulating the occurrence of the sum of the faces of two dice [i.e. dice(A) - 1, 2, 3, 4, 5 ,6 dice(B) - 1, 2, 3, 4, 4, 4, 5, 6, 6 ,6]. A dice is normal(each has an equal probability of occurrence) and another B dice i…

如何追踪每一笔记录的来龙去脉:一个完整的Audit Logging解决方案[上篇]

一、提出问题 在开发一个企业级 应用的时候,尤其在一个涉及到敏感数据的应用,比如财务系统、物流系统,我们往往有这样的需求:对于数据库中每一笔数据的添加、修改和删除,都需要有一个明确的日志,以便我们可…

执行shellcode的几种方式

首先写出汇编成功弹出计算器 #pragma comment(linker,"/section:.data,RWE") //data段可读写#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"") //不显示窗口#pragma comment(linker,"/INCREMENTAL:…

介绍针对企业级Flex开发的开源项目FlexibleShare

http://code.google.com/p/flexibleshare/ http://integratedsemantics.org/2009/05/19/flexibleshareair-dashboardportal-for-alfresco-livecycle-build1-available/ http://anvilflex.com/ 近日,开源的企业内容管理(ECM)系统供应商Alfresc…

取石子(七)

描述 Yougth和Hrdv玩一个游戏,拿出n个石子摆成一圈,Yougth和Hrdv分别从其中取石子,谁先取完者胜,每次可以从中取一个或者相邻两个,Hrdv先取,输出胜利着的名字。 输入 输入包括多组测试数据。 每组测试数…

html判断是安卓还是苹果手机,网页能够自己判断是pc端首页还是手机android和苹果。...

代码调用方式一 ( 推荐 兼容性好) 第一步: script typetext/javascript srcswfobject.js/script 第二步: p idplayera href/go/getflashplayerGet the Flash Player/a to see this player./p 第三步: var s7 new SWFObject(FlvPlayer2010.sw…

c构造函数和析构函数_C ++构造函数和析构函数| 查找输出程序| 套装1

c构造函数和析构函数Program 1: 程序1&#xff1a; #include <iostream>using namespace std;class Sample {private:int X;int Y;public:Sample(){X 0;Y 0;}Sample(int x, int y){X X;Y Y;}void print(){cout << X << " " << Y <&l…

我的项目的架构(三)

TranContext是一个比较重要的类,在这个类中,使用了反射方法,实现了根据配置文件动态创建类,实现了接口的作用. 1 publicabstractclassConfigurationFactory2 {3 publicConfigurationFactory()4 {5 //6 //TODO: 在此处添加构造函数逻辑7 //8 }9 publicstaticobjectCreateObject(…

1的个数

描述 小南刚学了二进制&#xff0c;他想知道一个数的二进制表示中有多少个1&#xff0c;你能帮他写一个程序来完成这个任务吗&#xff1f; 输入 第一行输入一个整数N&#xff0c;表示测试数据的组数(1< N<1000) 每组测试数据只有一行&#xff0c;是一个整数M(0< M…

单片机编程文件组织形式(个人编程规范)

1、外设或系统资源驱动函数组织形式。所有函数写在.c文件里面&#xff0c;.c最前面包含自身头文件。每个.c文件都有一个相对应的.h文件&#xff0c;其他文件或系统只调用.h文件。 2、.c文件除了最前面要包含自身头文件外&#xff0c;应该尽量全部是函数定义&#xff0c;接口信息…

计算机在我国开始被应用于,计算机应用推动自动化与信息化的发展

计算机应用推动自动化与信息化的发展【摘要】本文简单介绍了我国计算机应用的发展情况&#xff0c;分析了计算机应用同自动化和信息化之间的关系&#xff0c;通过计算机应用在我国各领域中的运用&#xff0c;来体现计算机应用对自动化和信息化的推动作用。【关键词】计算机&…

cobaltstrike生成一个原生c,然后利用xor加密解密执行

首先cobaltstrike生成一个原生c&#xff0c;我的是&#xff1a; /* length: 797 bytes */ unsigned char buf[] "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c" "\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\x31\xc0\xac…

tolowercase_JavaScript中的String toLowerCase()方法与示例

tolowercase字符串toLowerCase()方法 (String toLowerCase() Method) toLowerCase() Method is a string method in JavaScript, it is used to converts all alphabets in lowercase and returns the new string with lowercase alphabets. toLowerCase()方法是JavaScript中的…

这样就可以很方便的知道明天的天气了

今天在侧边栏加了一个实用的小东西——天气预报。它可以根据来访者的ip地址自动判断地区&#xff0c;并展现今天以及明天的天气预报。这样来看blog的时候就可以知道什么时候该去收衣服啦&#xff5e;哈哈&#xff01;实现代码其实很简单。就是套一个IFRAME&#xff0c;里面套个…

队花的烦恼一

描述 ACM队的队花C小经常抱怨&#xff1a;“C语言中的格式输出中有十六、十、八进制输出&#xff0c;然而却没有二进制输出&#xff0c;哎&#xff0c;真遗憾&#xff01;谁能帮我写一个程序实现输入一个十进制数n&#xff0c;输出它的二进制数呀&#xff1f;” 难道你不想帮…

计算机数学基础模拟试题,计算机数学基础》模拟考试试题.doc

PAGE / NUMPAGES《计算机数学基础(2)》模拟试题(1)一、单项选择题(每小题3分&#xff0c;共15分)1. 数值x*的近似值x0.121510-2&#xff0c;若满足( )&#xff0c;则称x有4位有效数字。A. B.C. D.2.设矩阵&#xff0c;那么以A为系数矩阵的线性方程组AXb的雅可比迭代矩阵为( )。…

压缩矩阵

压缩矩阵&#xff1a;指为多个值相同的元素只分配一个存储空间&#xff0c;对零元素不分配存储空间特殊矩阵&#xff1a;指具有许多相同矩阵元素或零元素&#xff0c;并且这些相同矩阵元素或零元素的分配有一定规律性 1、对称矩阵 对称矩阵&#xff1a;矩阵每个元素都有aijaj…