`
zachary.guo
  • 浏览: 487802 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

函数调用栈

 
阅读更多
        参考文章:http://liyiwen.iteye.com/blog/345525

        1. 一个函数调用动作可分解为:零到多个 PUSH 指令(用于参数入栈),一个 CALL 指令。CALL 指令内部其实还暗含了一个将返回地址(即 CALL 指令下一条指令的地址)压栈的动作。
        2. 几乎任何本地编译器都会在每个函数体之前插入类似如下指令:PUSH EBP;  MOV EBP ESP; 即,在程序执行到一个函数的真正函数体时,已有以下数据顺序入栈:参数,返回地址,EBP。

        函数调用的返回地址,正是调用指令 Call 的下一个指令的地址。那么,有了返回地址,就可以得到 Call 指令的位置了。有 Call 指令的位置又能干什么呢?Call 指令就是一个跳转指令,它可以让 IP(instruction point) 指向要跳转的指令的地址,从那里开始执行。对于函数调用来说,就是让 IP 指向被调用的函数的地址。Call 指令的操作数其实和被调用函数的地址有非常重要的关系。有了 Call 指令的操作数,就可以计算出被调用函数的地址。

        但仅仅有这个还不够。比如,A 调用了 B,那么在 A 函数中肯定有一个 Call 指令,但这个 Call 指令中的操作数是和 B 函数地址相关的,与 A 的函数地址直接关系不大(至少在没有其它信息的情况下,不能计算出 A 的地址)。而我们要得到的却是 A 函数的地址。所以,得向上再找一层,找到调用 A 函数的地方,那个地方的 Call 指令里的操作数才和 A 函数地址有关。也就是说,Z 函数调用了 A 函数,A 函数调用了 B 函数。现在要得到 A 函数的地址,我们得在 Z 函数里找 Call 指令的操作数。这时候 EBP 就派上用场了。本地编译器在每个函数体之前插入的指令(PUSH EBP; MOV EBP ESP)构造了一个巧妙的结构,使得我们可以顺着函数调用栈一层一层向上,找到所有调用关系。

        如何向上查找呢?我们看看函数调用时栈、EBP 的值的情况就知道了。假设现在函数在正 Z 函数内执行,那么此时栈和 EBP 的值可能是像下图这样的:
                                             
        我们先不管现在 EBP 指向的内存(0x000F)中的内容 XXX 是什么(要不然会是鸡生蛋生鸡的问题),总之目前在栈中的着色块中的内容是属于函数 Z 的参数,Z 执行结束后应该返回的地址以及 Z 函数的局部变量值。

        现在 Z 函数调用 A 函数,会先将传给 A 的参数压栈,然后将现在这个指令(就是"Call A")的下一个指令的地址压入栈中,以便 A 函数完后返回到 Z 中继续执行。然后进入 A 函数的内存空间,首先就是调用 PUSH EBP,也就是将 Z 的 EPB 的内容(地址 0x000F)压入栈中,然后再 MOV EBP ESP,让 EBP 有一个新的栈顶(此时栈顶中的内容不就是 Z 函数时 EBP 的内容么?),然后再将 A 函数的局部变量压入栈中,开始执行 A 函数的代码。这时,栈和 EBP 的情况就像如图所示了:
                                         
        这样就很清楚了,原来现在的 EBP 中的内容,正是上一级函数的 EBP 中的内容。而每一个函数的 EBP 指向的位置,向栈顶可以得到该函数的局部变量,向栈底可以得到函数的返回地址和参数。于是我们就可以根据这个结构层层向上,找到任何一层我们想找的函数 EBP,从而也就能得到相应的返回地址了。
  • 大小: 21.4 KB
  • 大小: 30.5 KB
分享到:
评论

相关推荐

    C++高效获取函数调用堆栈

    C++高效获取函数调用堆栈 在程序设计和开发过程中,出现问题是很正常的。这时候,快速找到问题所在,并确定程序的上下文环境就变得非常重要。函数调用堆栈的信息对于解决问题具有很大的帮助。传统的方法是使用 ...

    通过EBP EIP来找函数调用堆栈

    函数调用堆栈(也称为调用栈或执行栈)记录了程序中函数调用的顺序,这对于追踪代码执行流程,特别是错误定位非常有用。在x86架构的处理器上,通常使用两个寄存器——EBP(扩展基址寄存器)和EIP(指令指针寄存器)...

    C语言函数调用栈(一) - clover_toeic - 博客园1

    "C语言函数调用栈" C语言函数调用栈是一种常见的编程概念,它是指在程序执行过程中,函数调用时创建的一种栈结构。这种栈结构用于存储函数的局部变量、参数和返回地址等信息。 在C语言中,每个函数调用都会在内存...

    JavaScript函数调用堆栈loader

    JavaScript函数调用堆栈是编程过程中非常重要的一个概念,它记录了程序运行时函数的调用顺序。在JavaScript中,每当一个函数被调用,一个新的调用帧(call frame)就会被添加到调用堆栈上,包含了这个函数执行的所有...

    函数调用堆栈变化分析[参考].pdf

    在计算机科学中,函数调用堆栈(也称为调用栈或执行栈)是程序运行时内存中的一个重要组成部分,主要用于管理函数的调用与返回。本文将深入探讨函数调用堆栈的变化分析,以帮助理解程序执行过程。 首先,我们需要...

    linux C用户态调试追踪函数调用堆栈以及定位段错误.docx

    "Linux C用户态调试追踪函数调用堆栈以及定位段错误" Linux C用户态调试追踪函数调用堆栈以及定位段错误是指在 Linux 平台上使用 C 语言编写的程序中,如何追踪函数调用堆栈并定位段错误的方法。 在 Linux 平台上...

    浅谈在linux kernel中打印函数调用的堆栈的方法

    在Linux内核开发和调试过程中,理解函数调用堆栈是非常关键的,它能帮助开发者追踪问题的根源,尤其是在处理内核崩溃或者异常时。本文将深入探讨如何在Linux内核中打印函数调用的堆栈。 首先,Linux内核提供了一个...

    Win32环境下函数调用的堆栈之研究

    总之,Win32环境下的函数调用涉及到复杂的堆栈操作,包括保存和恢复寄存器、分配和释放栈空间以及传递参数。通过学习这些基本概念,我们可以更好地理解程序的内部工作原理,从而提高编程技能和调试能力。

    C语言函数调用栈(一)

    程序的执行过程可看作连续的函数调用。当一个函数执行完毕时,程序要回到调用指令的下一条指令(紧接...因此函数调用栈的实现与处理器寄存器组密切相关。Intel32位体系结构(简称IA32)处理器包含8个四字节寄存器,如下图

    函数递归调用堆栈分析.doc

    函数递归调用堆栈分析是指在计算机科学中,函数递归调用时,函数调用自身的过程中,如何使用堆栈来存储变量和参数的过程。堆栈是一种 lasts-in-first-out(LIFO)的数据结构,用于存储函数调用的参数和变量。 在...

    函数调用时栈与寄存器的变化

    ### 函数调用时栈与寄存器的变化 在计算机科学中,理解函数调用时栈及寄存器的变化对于深入掌握程序运行机制至关重要。本文将通过一个具体的例子来阐述函数调用过程中栈和寄存器的具体变化情况,并配有图示帮助理解...

    堆栈、栈帧与函数调用过程分析

    【应聘笔记系列】堆栈、栈帧与函数调用过程分析,C-C++堆栈指引

    JavaScript实现显示函数调用堆栈的方法

    JavaScript函数调用堆栈是程序执行过程中一种重要的信息,它记录了函数调用的顺序和层次关系,有助于开发者理解程序执行流程,特别是在进行错误调试和性能分析时。在现代浏览器中,通常可以通过console对象的trace...

    个人总结--函数堆栈调用

    在编程语言如C++中,函数堆栈调用是一个核心概念,它涉及到程序执行流程、内存管理和函数调用过程。本文将重点讨论函数调用时的堆栈操作,特别是与C++中的空类和默认函数相关的内容。 首先,让我们来看看空类`Empty...

    main函数调用子函数堆栈解析

    Main 函数调用子函数堆栈解析 在计算机程序设计中,函数调用是最基本的编程单元。函数调用会在内存中创建一个新的堆栈帧,该堆栈帧用于存放函数的实参、局部变量和返回地址等信息。在这个过程中,main 函数如何调用...

    C语言函数调用栈实例分析.md

    C语言函数调用栈实例分析.md

    函数调用时栈的变化[收集].pdf

    函数调用栈变化机制 函数调用是计算机科学中的一种基本概念,它是程序设计语言中的一种语句,用于调用已经定义的函数,以执行某些特定的操作。在函数调用过程中,栈空间的变化是非常重要的,因为它关系到函数的参数...

    msjexhnd Windows进程崩溃时捕获并输出错误信息、函数调用栈的例子

    一个在Windows进程崩溃时捕获并输出错误信息、函数调用栈的例子。对你制作自己的错误报告机制非常有用 这个类的使用方法很简单,只要把这个类加入到你的工程中并和你的程 序一起编译就可以了,由于在这个类的实现...

    VC中打印当前调用堆栈信息实例

    调用堆栈,也称为运行时堆栈或函数调用栈,是程序执行过程中存储函数调用信息的数据结构。每次函数调用都会在堆栈上分配空间,保存返回地址、参数和局部变量等信息。当函数返回时,这些信息会被释放,以便为新的函数...

Global site tag (gtag.js) - Google Analytics