函数栈平衡跟踪

例子:

struct stu{
    char name[20];
    int age;
    char* addr;
};

int inCall (char c,int n,char* hi, stu stu1){
    int locInt = 0x1234;
    char* locStr = "here i am";
    printf("%c\t0x%x\t%s\t0x%x\t%s\n",c,n,hi,locInt,locStr);
    printf("%s\t%d\t%s\n",stu1.addr,stu1.age,stu1.name);
    return 20;
}

void main()
{
    stu stu1;
    memset(&stu1,0,sizeof(stu1));
    memcpy_s(stu1.name,strlen("ZhangSan"),"ZhangSan",strlen("ZhangSan"));
    stu1.age = 0x30;
    stu1.addr = "Beijing";

    char* hi = "how are you?";
    inCall(‘A‘,0x70,hi,stu1);
    getchar();
}
  1. main函数的执行过程:

 栈空间:

  2.inCall函数的执行过程和栈空间:

时间: 2024-10-25 19:20:06

函数栈平衡跟踪的相关文章

broadcom6838开发环境实现函数栈追踪

在嵌入式设备开发中,内核为内核模块的函数栈追踪已经提供了很好的支持,但用户层的函数栈追踪确没有很好的提供支持.在网上收集学习函数栈跟踪大部分都是描述INTER体系架构支持栈帧的实现机制,或者直接给出glibc的现成库函数.但如果开发环境是broadcom相关方案,通常使用的是MIPS32的体系架构,并且C库使用的是更小的uclibc,虽然MIPS32体系架构中也定义了栈帧寄存器s8(类似于Inter体系架构中常见的ebp寄存器),但经过GCC编译器的优化选项控制后,通常在O1以上的优化就已经去除

函数堆栈平衡

int func(int a,int b,int c, int d) { 01243CE0 push ebp 01243CE1 mov ebp,esp 01243CE3 sub esp,0CCh 01243CE9 push ebx 01243CEA push esi 01243CEB push edi 01243CEC lea edi,[ebp-0CCh] 01243CF2 mov ecx,33h 01243CF7 mov eax,0CCCCCCCCh 01243CFC rep stos dwo

__cdecl 与 _stdcall 的栈平衡

各类关于VC的书中都多少写到: 1._stdcall调用约定:函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈. 2.__cdecl是C和C++程序的缺省调用方式.每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大.函数采用从右到左的压栈方式.注意:对于可变参数的成员函数,始终使用__cdecl的转换方式. __cdecl 说实在话,很多初学者对于这样的描述依然很不解,这两种调用方式究竟有什么区别呢? 我们先来看看以下代码: v

【链接】函数栈帧

本节通过反汇编可执行文件得到的文件,研究函数栈帧的相关内容: 栈帧整体示意图如下 示例代码 #include <stdio.h> #include <iostream> using namespace std; int z = 10; int add(int x, int y) { return x+y+z; } int inc20(int x) { int y = 10; return add(x, y); } int main(void) { int a = 30; a = i

c函数调用过程原理及函数栈帧分析

转载自地址:http://blog.csdn.net/zsy2020314/article/details/9429707       今天突然想分析一下函数在相互调用过程中栈帧的变化,还是想尽量以比较清晰的思路把这一过程描述出来,关于c函数调用原理的理解是很重要的. 1.关于栈 首先必须明确一点也是非常重要的一点,栈是向下生长的,所谓向下生长是指从内存高地址->低地址的路径延伸,那么就很明显了,栈有栈底和栈顶,那么栈顶的地址要比栈底低.对x86体系的CPU而言,其中 ---> 寄存器ebp(

函数栈帧

在函数栈帧中 一般包含以下几类重要信息 1 局部变量 :为函数局部变量开辟的内存空间 2 栈帧状态值:保存前   栈帧的顶部和底部 3 函数返回地址:保存当前函数调用前的“断点”信息,也就是函数调用前的指令位置 以便在函数返回时能够恢复到函数被调用前的代码区中继续执行指令. EIP:指令寄存器:其内存放着一个指针,该指针永远指向下一条等待执行的指令地址 可以说 控制了 EIP 寄存器的内容,就控制了进程 我们让EIP指向哪里,CPU就会去执行哪里的指令. EIP劫持原理.

scala tail recursive优化,复用函数栈

在scala中如果一个函数在最后一步调用自己(必须完全调用自己,不能加其他额外运算子),那么在scala中会复用函数栈,这样递归调用就转化成了线性的调用,效率大大的提高.If a function calls itself as its last action, the function's stack frame can be reused. This is called tail recursion.=> Tail recursive functions are iterative proc

谈谈arm下的函数栈

引言 最近无聊看了看征服C指针,看到函数的不定参数时想起在这方面还没有做过一些总结,只是略微了解一些,意识到其实完全不需要借用va_list,va_start,va_arg这些标准函数也可以自己实现操作,具体我们来看看. 函数栈 首先我们需要了解一下linux下一个进程的内存地址空间是如何布局的,在linux中,0~3G的虚拟地址为进程所有,3G~4G由内核所使用,每一个进程都有自己独立的0~3G内存地址空间.当进程进行函数调用时,我们都知道传入被调用函数的参数是通过栈进行操作的,这里我们只需要

Linux 下函数栈帧分析

1.关于栈 对于程序,编译器会对其分配一段内存,在逻辑上可以分为代码段,数据段,堆,栈 代码段:保存程序文本,指令指针EIP就是指向代码段,可读可执行不可写 数据段:保存初始化的全局变量和静态变量,可读可写不可执行 BSS:未初始化的全局变量和静态变量 堆(Heap):动态分配内存,向地址增大的方向增长,可读可写可执行 栈(Stack):存放局部变量,函数参数,当前状态,函数调用信息等,向地址减小的方向增长,非常非常重要,可读可写可执行.如下图所示: 首先必须明确一点也是非常重要的一点,栈是向下