函数传递参数的本质
研究实验5
问题引出:我们经过之前的研究已经知道了函数就是汇编中的子程序这样一个概念,那么但是函数的参数是如何传递呢,是汇编语言学习中参数传递的哪种方式呢?
问题研究:
图1-2 a.exe汇编代码
从图中的汇编代码我们可以清晰的发现,C语言中传递参数是通过栈来传递参数,这在之前汇编语言中是有介绍的。
图3 b.exe对应汇编代码
从图中的汇编代码可以看出,showchar 是根据第一个变量n值来确定要显示多少个字符的。
下面来研究这样一个问题:printf函数功能很强大,原因在于它对于参数个数不限制,它到底是怎么样来处理这样一个过程的?
观察printf函数,我们其实容易发现,无论我们用printf函数对屏幕输出什么,printf()函数括弧中第一个量总是一个字符串,所以,我们在此推测,字符串是printf函数的第一个变量(虽然C语言中没有字符串变量)。而且根据我们已知的事实是:”…”字符串中的内容决定了其后面变量的个数(之前学习C语言时我们发现如果类似于%d这样的输出符,如果其个数和后面变量的个数不匹配,那么编译器就会报错)。并且根据我们已经掌握的C语言知识,我们发现,%字符的个数决定了其后面变量的个数,即%字符为0个时,其后没有变量,%字符为n个的时候,其后的变量个数为n。
基于此原理我们编写一个伪printf函数
详情见附件2
实验结果只能显示字符串以及大于零的数,尚需改进
改进中!!!!!!!
未解决问题:
虽然知道了传递参数是通过栈的方式,但是如何知道要入栈多少个数,是否是编辑器决定的?
研究总结
通过这个实验最大的收获是,知道了函数传参是通过栈的方式进行参数传递的,知道了printf函数的接受参数的机制。但是想提出的一个问题是,为什么要对printf函数进行研究,其对于后期学习有什么作用影响?
补充总结部分:
在此,再次补充一下调用函数过程机制:
首先需要明确一点,C语言中函数都是带括号的,其次,括号中的逗号隔开的都是参数!!,事实上,这一点是十分重要的。比如printf函数第一个字符串也是一个参数,我们不能忽略了它是参数这样一个事实!!这就是说,在入栈的时候,它也入栈了(入栈的是首地址)
从这里也能看出用指针指向字符串的优越性。
下面介绍一下调用函数的机制:
首先,在遇到一个即将被调用的函数时:
第一步:将所有的参数入栈(括号最右边的参数最先入栈),可以认为是准备工作
第二步:开始调用函数,即call ,将IP入栈
第三步:进入子函数,首先将BP入栈。
所以我们在取参数的时候,务必要十分明确上述过程才可以,尤其是printf函数的实现过程,必须要深入理解上述原理!