您的位置:首页 > 编程语言

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

2016-06-10 19:48 549 查看

现象

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



从以上程序中我们可以知道,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的值

程序如下:



运行结果:



原因就不在这里多说了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息