• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C语言程序的机器级表示

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

过程调用的机器级表示

特别说明该表示是基于IA-32指令系统,x86 64指令系统不同于IA-32

机器级表示

可执行文件的存储器映像

调用过程

 

IA-32的寄存器使用约定
– 调用者保存寄存器:EAX、EDX、ECX
    当过程P调用过程Q时,Q可以直接使用这三个寄存器,不用
    将它们的值保存到栈中。如果P在从Q返回后还要用这三个寄
    存器的话,P应在转到Q之前先保存,并在从Q返回后先恢复
    它们的值再使用。
– 被调用者保存寄存器:EBX、ESI、EDI
    Q必须先将它们的值保存到栈中再使用它们,并在返回P之前
    恢复它们的值。
– EBP和ESP分别是帧指针寄存器和栈指针寄存器,分别用来指
    向当前栈帧的底部和顶部。

过程调用过程中栈和栈帧的变化 (Q为被调用过程)

 

看一个简单的例子

 

过程解析

一个C过程的大致结构如下:
– 准备阶段
    • 形成帧底:push指令 和 mov指令
    • 生成栈帧(如果需要的话):sub指令 或 and指令
    • 保存现场(如果有被调用者保存寄存器) :mov指令
– 过程(函数)体
    • 分配局部变量空间,并赋值
    • 具体处理逻辑,如果遇到函数调用时
        – 准备参数:将实参送栈帧入口参数处
        – CALL指令:保存返回地址并转被调用函数
    • 在EAX中准备返回参数
– 结束阶段
    • 退栈:leave指令 或 pop指令
    • 取返回地址返回:ret指令

 

过程调用参数传递举例

 

 看一个递归函数的例子

int nn_sum ( int n)
{
    int result;
    if (n<=0 )
        result=0;
    else
        result=n+nn_sum(n-1);
    return result;
}

 

我们可以看出来,递归函数在不断的压栈生成栈帧,且没有到达最后一个递归的函数,他的栈帧并没有进行释放,所以

递归函数的空间和时间的开销都非常大(当达到他的极限值就会出现暴栈的情况)我们可以尽量不适用递归函数

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
VisualStudio2005编写C程序出错:errorC2143,)前缺少*发布时间:2022-07-14
下一篇:
C#中使用this为类添加方法发布时间:2022-07-14
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap