`
hulianwang2014
  • 浏览: 726284 次
文章分类
社区版块
存档分类
最新评论
  • bcworld: 排版成这样,一点看的欲望都没有了
    jfinal

函数调用的过程stack动态分析

 
阅读更多

一段代码的stack调用分析:

下面分析的代码:

/*
 * =====================================================================================
 *
 *       Filename:  stack.c
 *
 *    Description:  gdb 栈的使用,对栈的分析过程
 *
 *        Version:  1.0
 *        Created:  2013年02月10日 13时48分02秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  LeoK, 
 *   Organization:  
 *
 * =====================================================================================
 */
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#define  	MAX		(1UL<<20)

typedef unsigned long long u64;
typedef unsigned int u32;

u32 max_addend = MAX;
u64 sum_till_MAX(u32 n)
{
	u64 sum;
	n++;
	sum = n;
	
	if (n < max_addend)
	{
		sum += sum_till_MAX(n);
	}
	return sum;
}

int main(int argc, char** argv)
{
	u64 sum = 0;
	if (argc == 2 && isdigit(*(argv[1])))
		max_addend = strtoul(argv[1], NULL, 0);
	if (max_addend >= MAX || max_addend == 0)
	{
		fprintf(stderr, "Invalid number is specidied\n");
		return 1;
	}
	sum = sum_till_MAX(0);
	printf("sum(0..%lu) = %llu\n", max_addend, sum);
	return 0;
}

图1 main函数的汇编代码

其中main调用了sum_till_MAX

步骤1:图1 movl $0x0, (%esp),这个汇编代码就是main 调用sum_till_MAX的准备工作.

主要完成的就是stack.c:51行,把0函数参数传进来(代码是图2).

图2

执行完步骤1此时的栈如下,因为程序执行的时候都是逻辑地址,所以栈地址就假设开始为0x8fff0000开始

Address Content Expain

0x8fff0000 0x0 $esp指向这里

0x8ffefffc ??? 内容random

0x8ffefff8 ??? 内容random

0x8ffefff4 ??? 内容random

0x8ffefff0 ??? 内容random

0x8ffeffec ??? 内容random

0x8ffeffe8 ??? 内容random

0x8ffeffe4 ??? 内容random

0x8ffeffe0 ??? 内容random

图3 步骤1完成之后栈的内容

注意:如果函数是多参数的,那么参数的入栈顺序是从右向左入栈,such as

int sum(int a, int b, int c)

这个函数的入栈顺序是push c =>push b=> push a这个做的原因可能是函数执行可变参数的原因吧

步骤2 main函数调用call sum_till_MAX这个函数首先把eip压栈,eip就是程序的执行的下一个地址,此时的stack如图4

Address Content Expain

0x8fff0000 0x0 push 0

0x8ffefffc 0x0804858d 寄存器eip esp指向这里

0x8ffefff8 ??? 内容random

0x8ffefff4 ??? 内容random

0x8ffefff0 ??? 内容random

0x8ffeffec ??? 内容random

0x8ffeffe8 ??? 内容random

0x8ffeffe4 ??? 内容random

0x8ffeffe0 ??? 内容random

图4步骤2完毕stack情况

下面进入到sum_till_MAX函数

sum_till_MAX的反汇编代码如下:


图5sum_till_MAX函数汇编代码

步骤1 push %ebp把调用sum_till_MAX函数的ebp进行压栈,恢复上一层栈帧的时候使用,此时栈如下:

Address Content Expain

0x8fff0000 0x0 push 0

0x8ffefffc 0x0804858d 寄存器eip

0x8ffefff8 $ebp 上一个栈帧的栈基址 $esp指向这里

0x8ffefff4 ??? 内容 random

0x8ffefff0 ??? 内容random

0x8ffeffec ??? 内容random

0x8ffeffe8 ??? 内容random

0x8ffeffe4 ??? 内容random

0x8ffeffe0 ??? 内容random

步骤2 mov %esp , %ebp这段代码表示把ebp指向esp也是就是地址0x8ffefff4地址。

步骤3 sub $0x28 , %esp表示把esp指针指向0x8ffefff4-0x28=0x8FFEFFCC,也就是为函数内部开辟新的占空间,是2*16+8=40个字节。

此时栈如下:

Address Content Expain

0x8fff0000 0x0 push 0

0x8ffefffc 0x0804858d 寄存器eip

0x8ffefff8 $ebp 上一个栈帧的栈基址

0x8ffefff4 ??? $ebp指向这里

0x8ffefff0 ??? 内容random

0x8ffeffec ??? 内容random

0x8ffeffcc ??? esp指向这里

步骤4 addl $0x1, 0x8(%ebp)这段代码是把0拿出来(%ebp+0x8),进行++

步骤5 mov 0x8(%ebp), %eax 把变量n放到eax寄存器中

步骤6 mov 0x0 , %edx 把寄存器edx清零

步骤7 mov %eax , -0x10(%ebp)这个是sum =n 把n赋值给sum

步骤21 leave指令为删除栈帧的执行,它执行与1和2相反的处理,以释放以前的栈。

步骤22 ret 为子程序返回指令,将栈中保存的返回地址POP到程序计数寄存器中,将控制权返回给调用者.


分享到:
评论

相关推荐

    C# 获取调用函数 参数名称和值

    在C#编程中,获取调用函数的参数名称和值是一项常见的需求,特别是在日志记录、调试或动态处理参数时。下面将详细讲解如何在C#中实现这一功能。 首先,我们要了解C#中的反射机制。反射是.NET框架提供的一种强大工具...

    追踪谁调用了函数

    调用堆栈(Call Stack)是程序在执行过程中,函数调用记录的一种数据结构。每次函数调用都会在堆栈上创建一个新的帧(Frame),存储返回地址和局部变量等信息。通过遍历这个堆栈,我们可以逆序地查看函数调用的顺序...

    函数调用中堆栈的个人理解共4页.pdf.zip

    函数调用涉及到堆栈(Stack)这一数据结构的使用,它在程序执行过程中起着至关重要的作用。堆栈是计算机内存管理的一种方式,它遵循“后进先出”(Last In, First Out, LIFO)的原则。在这里,我们将深入探讨函数...

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

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

    Ftrace Kernel Hooks-More than just tracing.pdf

    Ftrace 是 Linux 内核中的一种追踪机制,能够记录和分析内核中的函数调用过程。Ftrace 的主要组件包括 Function Tracer、Function Graph Tracer、Function Profiler、Stack Tracer 等。这些组件可以帮助开发者和系统...

    用户空间程序的函数跟踪器BSP.7z

    首先,BSP的基本功能是对用户空间程序中的函数调用进行记录和分析。它可能通过插入钩子函数或者利用编译器的调试信息来捕获函数的进入和退出。当函数被调用时,BSP会记录下调用的上下文,包括调用者信息、参数值、...

    The Run-time Heap and Stack

    `foo`函数中的`z`和`ch`是在函数调用过程中分配的局部变量,它们存储在栈上,在函数退出时自动释放。 总之,堆和栈在内存管理中扮演着不可或缺的角色,理解它们的工作原理对于编写高效、无错误的程序至关重要。

    cpp打印调用堆栈

    在C++编程中,调用堆栈(也称为呼叫堆叠或调用栈)是程序执行过程中内存中存储的函数调用记录。每当一个函数被调用,一个新的栈帧(stack frame)就会被创建,包含局部变量、返回地址和其他相关信息。当函数返回时,...

    stack用法 软件开发技术学习辅助

    在计算机科学中,特别是在软件开发中,栈是不可或缺的一部分,它被广泛应用于各种场景,如函数调用、内存管理、编译器设计等。下面将详细介绍栈的基本概念、操作以及在软件开发中的应用。 一、栈的基本概念 1. ...

    Find CALL Tool(带源码).zip

    6. **动态调度**(Virtual Function/多态):在面向对象编程中,通过虚函数表实现动态调度,使得函数调用可以根据对象的实际类型而非声明类型来确定执行哪个函数,这是多态性的一个体现。 7. **性能优化**:了解...

    C++数据结构实现之Stack.zip

    - **递归**:递归过程本质上也是利用栈来保存每次函数调用的状态。 - **内存管理**:某些操作系统使用栈来分配和释放内存块。 5. **优化考虑**: - 当使用数组实现栈时,需要预估最大元素数量以避免频繁的动态...

    Collecting the call stack in real time

    调用栈(Call Stack)是一种用于存储程序执行期间函数调用信息的数据结构。当一个函数被调用时,它的局部变量、参数和其他信息会被压入调用栈;当该函数执行完毕后,这些信息会被弹出调用栈。通过查看调用栈,可以...

    A beautiful stack trace pretty printer for C++.zip

    1. **栈帧(Stack Frame)**:每个函数调用都会创建一个栈帧,存储参数、局部变量以及返回地址。栈帧的结构有助于追踪函数调用的上下文。 2. **堆栈(Stack)**:在计算机内存中,堆栈是一个后进先出(LIFO)的数据...

    C语言泛型stack操作算法

    栈是一种后进先出(LIFO, Last In First Out)的数据结构,常用于实现递归、表达式求值、函数调用等场景。 “泛型”一词通常在高级编程语言中出现,如Java或C#,用来表示可以处理多种数据类型的代码。然而,在C语言...

    从StackTrace获取调用程序集

    这可以通过在异常处理代码中或者在需要检查堆栈跟踪的任何地方,使用StackTrace的构造函数来完成。例如: ```csharp StackTrace stackTrace = new StackTrace(); ``` 接下来,我们需要访问StackTrace中的帧(Frame...

    用ollydbg静态分析和动态追踪的一般步骤动画教程

    6. **堆栈分析**:通过"Stack"窗口了解函数调用的参数传递和返回值。 7. **动态API调用分析**:在程序运行过程中,记录并分析API调用,以揭示其功能和行为。 动画教程可能包括以上步骤的演示,通过动态的画面展示...

    关于堆栈(mac堆栈操作文档)

    例如,在函数调用过程中,栈帧(stack frame)会被用来存放局部变量和函数参数,当函数执行完毕后,这些数据会自动释放,从而实现内存的有效管理。 - **错误处理与调试**:在软件开发中,堆栈也是错误处理和调试的重要...

    windows进程中的内存结构

    举例来说,下面的代码展示了函数调用过程中栈的变化。函数`func`接受三个参数,并在函数体内打印出它们的内存地址。当`func`被调用时,参数1、2、3依次压入栈中。在函数内部,这些参数的值被赋给局部变量var1、var2...

    Obtaining a stack trace in C upon SIGSEGV

    具体而言,它会从当前线程的上下文中获取堆栈指针,并沿着堆栈逐层解析出函数调用序列。这样可以提供关于程序崩溃时的执行路径的信息,帮助开发者定位问题。 #### 使用方法 ##### LD_PRELOAD 黑客技巧 为了使这段...

    c函数资源

    探索C语言函数和栈分析的过程中,可以参考经典的教材如《C语言程序设计》(K&R),以及在线资源如GCC文档,Stack Overflow问答等。 通过深入学习和实践C语言库函数,开发者能更好地掌握C语言的精髓,而对栈的理解...

Global site tag (gtag.js) - Google Analytics