没有被调用的函数其代码为什么会被执行?

现象

首先我们运行下面一段代码:


从以上程序中我们可以知道,main函数调用函数fun1,函数fun1和main函数都没有调用函数fun,因此,我们认为函数fun中的"fun is run.."和 "you are done.."都不会被打印。

且main函数中的打印语句“begin run..”和“main: you should run here”都应该被打印


让我们来看看运行结果:


很明显,运行结果和我们预想的完全不同,这是为什么呢?


想要知道这其中的原因,让我们先回忆一下函数调用过程的栈帧:

栈帧

一个过程调用包括将数据(以过程参数和返回值的形式)和控制从代码的一部分传递到另一部分。另外,它还必须在进入时为过程的局部变量分配空间,并在退出时释放空间。

大多数机器,只提供转移控制到过程和从过程中转移出控制这种简单的指令。数据传递,局部变量的分配和释放通过操纵栈来实现的。为单个过程分配的那部分栈称为栈帧


下图是函数调用过程中的栈帧结构:



了解了栈帧的结构,让我们分析为什么没有被调用的函数会被执行?

原因分析

让我们根据汇编代码分析该程序


根据汇编指令,我们知道可以知道,main函数中调用函数fun时,将fun函数参数b,a压栈,返回地址0x080484b5压栈。

根据汇编代码,我们可以大致构建出main函数的栈帧:


查看fun1汇编代码:


通过读取fun1函数的代码,

int *p=&a;

p中保存的是a的地址p=ebp+8

--p;

p中保存a的空间的前一个空间的地址,为p=ebp+4,是函数调用后的返回地址

*p=fun;

将ebp+4空间中的值置为0x8048414(fun函数的地址)


总结原因

因此,函数调用的返回地址本应该是main函数中call指令的下一条指令的地址,而fun1函数中将函数调用后的返回地址修改为fun函数的地址,那么,当fun1函数调用完成后将跳转到返回地址处,该返回地址是fun函数的地址,那么,自然而然fun函数中的代码就被执行


不用变量名,修改变量b的值

程序如下:

运行结果:

原因就不在这里多说了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值