c语言函数调用原理

c语言函数被调用时,寄存器和内存都干了啥?

源代码:
#include “stdio.h”
unsigned char test1(unsigned char a);
int main()
{
unsigned char i,s,z = 0;
i = 1;
s = i;
z = test1(i);
i = z;
while(1);
}

unsigned char test1(unsigned char a)
{
unsigned char b;
b = a;
return b;
}

有一点c语言基础的都可以看懂这段代码是什么意思吧,接下来了解CPU底层是如何处理这段代码的吗,话不多述,直接进入正题:

Main初始化:刚开始BP = 18ff88 , SP = 18ff4c
Push BP BP = 18ff88 , SP = 18ff48 , 由于bp进栈,所以sp -= 4
Mov BP SP BP = 18ff48 , SP = 18ff48
Sub SP 4CH BP = 18ff48 , SP = 18FEFC 为函数局部变量申请空间
PUSH BX
PUSH SI
PUSH DI BP = 18ff48 , SP = 18FEF0
Lea DI [BP-4CH] DI = 18FEFC
Rep stos dword ptr[di] DI = 0018ff48 初始化bp到sp76字节的空间,用来存局部变量

Mov byte ptr [bp-0CH] 变量初始化 存在bp到sp段,变量变换本质即改变内存中某段的值,或者说是栈里面的值

如果遇到了函数:
函数调用了内存[bp-4]的变量
Mov cl,byte ptr[bp-4]
Push cx 将需要的变量放到栈里面 sp = 18feec
Call 。。。。 IP指向被调用的函数 此处sp-=4 sp = 18fee8

Push bp sp = 18fee4
Mov BP SP BP = 18fee4, SP = 18fee4
Sub SP 44H BP = 18fee4, SP = 18FEA0 为什么是44h,因为函数变量比main少8byte,然后那多出的64字节也没有用到,存了一堆的CCH;
PUSH BX
PUSH SI
PUSH DI
lea edi,[ebp-44h] di = 0018FEA0 SP = 0018FE94 BP = 0018FEE4
mov ecx,11h
mov eax , 0CCCCCCCCh
rep stos dword ptr [edi]

mov al,byte ptr [ebp+8] 在这个函数被调用的时候,将一部分形参压入栈,这部分数据就要开始作用了,此处被赋值。。。。。参看下条指令
mov byte ptr [ebp-4],al

mov al,byte ptr [ebp-4] 将要返回的值保存在al里面

函数返回要做这些事:
pop edi
pop esi
pop ebx 这3条是将被保护的寄存器恢复
mov esp,ebp 恢复main栈顶指针
pop ebp 恢复main栈基地址
ret 返回之后main照常进行

总结:
函数调用的过程是这样的,假设地址由下往上递减:

低地址

SP(fun)
此处存放fun的形参
BP(fun)
此处存放被调函数的形参
SP(main)
此处存放main的形参
BP(main)

高地址

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值