发新话题
打印

[转载]C参数传递探索

[转载]C参数传递探索

文章作者:D哥

  C参数传递探索
  在开始前,你应该对堆栈有些了解,堆栈是一种后进先出的数据结构属于线形表的范畴。按存储结构分,又分为顺序栈和链栈。堆栈是在内存开出的一快特殊区域。
现在我就对堆栈在C语言中的应用做一个较深入的分析。
  学过汇编的人都知道,在主程序中调用子程序的时候传递参数的方式可以是寄存器,内存,和堆栈。在C中实参的传递就是用的堆栈。
我们来看一段不完整的代码。
fun(int c,int d)
(int e=10;
c=6;
d=7;
...
...
)
main()
{...
...
fun(10,20);
...
...
}
我们可以通过汇编代码,来看一下C在传递参数的时候是怎么做的。

子程序部分汇编代码:
    fun:
         push ebp       ;ebp压栈;
         mov ebp,esp     ;esp送入ebp,可以用ebp寻址内存;
         sub esp,4      ;为内部变量e分配内存;
         mov [ebp-4],10   ;处始化内部变量;
         mov [ebp+8],6    ;修改参数C;
         mov [ebp+12],7   ;修改参数d;
         ...
         ...
         ret
主程序的部分汇编代码
      main:  
         ...
         ...
         mov [esp],10    ;实参进栈;
         mov [esp+4],20  ;实参入栈;
         call fun
  

          前                          后
------------------------------低    -----------------------
            e                            10
------------------------------        -----------------------
            ebp                         ebp
------------------------------        -----------------------
           函数返回地址             函数返回地址
------------------------------       -----------------------
            10                            6
------------------------------       ------------------------
            20                         7
-------------------- --------- 高   -------------------------
   

   
可以看出,实参首先压栈,然后自动对call的下一句指令的地址压栈,这是call语句自动完成的。然后控制转入子程序,保存esp的内容到ebp
把ebp做为指针寻址内存,当然这不是必须的,可以直接用esp直接寻址,这样寻址速度更快,但可能不太容易理解,所以选择了前者。
在学习汇编语言中如果用堆栈传递参数,到后来在ret后面要加个偶数,以免破坏了堆栈平衡,但是在C中你将看不到那个偶数,因为C语言规定,当返回控制时,由C语言使堆栈恢复到它的原始值,所以汇编语言过程的最后一条指令只是简单的RET而不必使用带常数的RET指令。
  

                                    作者:D哥
人情如冰六月寒,花做一份艳,为谁笑人间? 如果任何人发现我转载的有图像的文章中图像失效或者文章有问题,请及时短消息通知我。先谢谢。::)) coup de foudre

TOP

发新话题