首页 > 【汇编】C++ 函数调用之——有参无返回调用(传指针)

【汇编】C++ 函数调用之——有参无返回调用(传指针)

2019独角兽企业重金招聘Python工程师标准>>> hot3.png



一.传值

二.传指针(地址)

传地址调用函数顾名思义,就是向被调函数传递的是一个地址值,而不是数据内容,这个地址通常是一个32位无符号整数,表示为十六进制就是形如:0x???? ????,在实际内存中是以(DWORD)形式存放 ,这就是指针类型在内存中通常占用4字节的原因。

有源代码:



void func(int *b){*b=10;
}int main(int argc,char *argv[])
{//call funcint a;func(&a);return 0;
}
这段代码就是通过func函数修改main函数的一个局部变量a。



main函数中对应的汇编码如下所示:

//call func
int a;
func(&a);
00911438  lea         eax,[ebp-0Ch]  
0091143B  push        eax  
0091143C  call        009111D1  
00911441  add         esp,4  
//可以看到,传指针时,有一个lea指令,该指令是将局部变量a的地址也就是ebp-0ch传送给寄存器eax
//然后将eax压栈,换句话说压栈的内容是&a(ebp-0ch)
//后续操作和之前介绍的传值调用一致

为了更直观一些,我们在内存窗口查看这个地址放在哪儿了。然后由这个地址找到a所在内存单元,看是不是0xCCCCCCCC(请参考)

&a=0x0109FEE0



PUSH &a



再看看func函数:

*b=10;
009113EE  mov         eax,dword ptr [ebp+8]  
//从栈底偏移+8处取出调用时push的&a,从内存中也可以看出正好是放在那里的
009113F1  mov         dword ptr [eax],0Ah  
//注意这里eax存的是&a,作为地址然后找到对应的内存单元,向里面传送10,就是实现了*b=10
内存中是怎么样的呢?

0x0109FEE0处:

可以看到确实变成了0a

和传值调用唯一的不同就是参数压栈时压的是地址而已。

如果需要向函数传一个对象,而这个对象占用很大的一块内存,如果使用传值方式,则需要在被调函数栈底下面(参数表)push一个对象,相当于完全拷贝这个对象,占用同样的内存空间。

而如果使用传指针,那么仅仅需要push一个4字节的地址值而已,对象没有发生拷贝,大大节省了内存和时间。这就是使用指针的高效处。

转载于:https://my.oschina.net/ybusad/blog/147395

更多相关:

  • 51 三菱PLC可读不可写Q:MT8102IQ和三菱Q系列PLC通讯,屏无法写入PLC,但是可以读取PLC的状态和数值?A:PLC程序中"允许RUN中写入"打钩,程序下载重启后解决。52 控制不了输入点Q:触摸屏做了三菱PLC的X点的元件,但是控制不了X输出?A:是的,PLC端X点无法通过触摸屏控制输出,屏上只能做X点的显示。53 M...

  • 传统方法(仅适用于普通项目):   1、在vscode中安装 Live Server 插件: 2、安装成功后,vscode右下角会有 Go Live 标识点击: 3、cmd ipconfig 查询自己电脑的ip地址: 4、复制地址替换端口前的地址(http://127.0.0.1:8080修改为http://192.168....

  • ngx_http_geo_module模块,默认情况下,nginx会加载,除非人为的 --without-http_geo_module。 这个模块提供了一个非常好用的geo指令,可以用它来创建变量,诞生其值依赖于客户端IP地址。 ngx_http_geo_module 模块官网地址 http://nginx.org/en...

  • uboot启动Linux内核过程分为4大步骤: 问题2: uboot阶段DDR的分区的问题 上述步骤2和步骤4中,有将uboot/kernel拷贝纸DDR的步骤,具体要拷贝到DDR的什么位置呢? 分清楚这两个概念: 链接地址:链接时指定的地址(指定方式为:Makefile中用-Ttext,或者链接脚本) 运行地址:程序实际运行...

  • 在Linux系统中,以32bit x86系统来说,进程的4GB内存空间(虚拟地址空间)被划分成为两个部分 ------用户空间和内核空间,大小分别为0-3G,3-4G。        用户进程通常情况下,只能访问用户空间的虚拟地址,不能访问到内核空间。          每个进程的用户空间存放用户的程序和代码(堆栈,数据区,代码区等)...

  • 更多内容,欢迎关注微信公众号:全菜工程师小辉~前言在笔者上一篇博客,详解了NIO,并总结NIO相比BIO的效率要高的三个原因,彻底搞懂NIO效率高的原理。这篇博客将针对第三个原因,进行更详细的讲解。首先澄清,零拷贝与内存直接映射并不是Java中独有的概念,并且这两个技术并不是等价的。零拷贝零拷贝是指避免在用户态(User-space)...

  • 一、预备知识—程序的内存分配  一个由c/C++编译的程序占用的内存分为以下几个部分  1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈,如果还不清楚,那么就把它想成数组,它的内存分配是连续分配的,即,所分配的内存是在一块连续的内存区域内.当我们声明变量时,那么编译器...

  • 我的爱机是一台ThinkPad T420,原装三星DDR 1333 4G内存一根,还剩一根内存位置,最近趁京东6.18促销,准备增加一根物理内存。为了确保兼容性,觉得仍然选购DDR 1333 4G内存,于是购买了金士顿这款,比如DDR3 1600的还贵。 这个安装过程完全参照该内存的网页提示进行 这里简单记录一下,以备...

  • 陪伴我多年的老本ThinkPad T420渐渐垂垂老矣, 我想更新一下可以更新的部分, 比如将2.5寸HDD更换为SSD, 将单条4G内存再增加一根, 凡此种种想法, 可能最后归结为如何获取该笔记本的硬件配置信息, 在windows下面使用鲁大师之类的检测软件, 也许很好搞定,但是在Ubuntu 14.04平台上如果办到呢? 很简单...

  • 一.内存错误出现的场景 这几天在重构ATS插件代码的过程中遇到了烦人的内存泄露问题, 周五周六连续两天通过走查代码的方法,未能看出明显的导致内存错误的代码, 同时也觉得C和C++混合编程得到一个动态库, 在一个.cpp主文件中,即用new又用malloc来动态分配内存, 可能会导致内存错误.后来网上调研和查资料发现, new和mal...

  • 草色新雨中, 松声晚窗里。之前我们学习 Power Query 都是用鼠标就完成了很多复杂的操作。虽然 PowerQuery 已经将大部分常用功能内置成到功能区。基本能完成我们大部分的报表自动化功能。但是总有些复杂的或者个性化的问题是开发团队没有预先想到的,这时我们就需要学习 M 语言。一、M 语言在哪里?M语言的函数公式有三个地...

  • 前言从2020年3月份开始,计划写一系列文档--《小白从零开始学编程》,记录自己从0开始学习的一些东西。第一个系列:python,计划从安装、环境搭建、基本语法、到利用Django和Flask两个当前最热的web框架完成一个小的项目第二个系列:可能会选择Go语言,也可能会选择Vue.js。具体情况待定,拭目以待吧。。。基本概念表达式表...

  • 1.1函数1.1.1什么是函数函数就是程序实现模块化的基本单元,一般实现某一功能的集合。函数名:就相当于是程序代码集合的名称参数:就是函数运算时需要参与运算的值被称作为参数函数体:程序的某个功能,进行一系列的逻辑运算return 返回值:函数的返回值能表示函数的运行结果或运行状态。1.1.2函数的作用函数是组织好的,可重复使用的,用来...

  • 原标题:基于Python建立深度神经网络!你学会了嘛?图1 神经网络构造的例子(符号说明:上标[l]表示与第l层;上标(i)表示第i个例子;下标i表示矢量第i项)单层神经网络图2 单层神经网络示例神经元模型是先计算一个线性函数(z=Wx+b),接着再计算一个激活函数。一般来说,神经元模型的输出值是a=g(Wx+b),其中g是激活函数(...

  • 在学习MySQL的时候你会发现,它有非常多的函数,在学习的时候没有侧重。小编刚开始学习的时候也会有这个感觉。不过,经过一段时间的学习之后,小编发现尽管函数有很多,但是常用的却只有那几个。今天小编就把常用的函数汇总一下,为大家能够能好的学习MySQL中的函数。MySQL常使用的函数大概有四类。时间函数、数学函数、字符函数、控制函数。让我...