C函数参数传递探索(学过汇编的可以看懂)
黑色星空 :: 黑色星空 :: 编程算法(转逻辑为现实) :: C语言编写
第1页/共1页
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指令。
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指令。
niusan521- 帖子数 : 210
注册日期 : 12-01-09
黑色星空 :: 黑色星空 :: 编程算法(转逻辑为现实) :: C语言编写
第1页/共1页
您在这个论坛的权限:
您不能在这个论坛回复主题