C语言函数调用堆栈框架

堆栈是C语言程序运行时必须的一个记录调用路径参数的空间

      -- 函数调用堆栈框架
      -- 传递参数
      -- 保存返回地址
      -- 提供局部变量空间

* 函数的返回值默认使用 eax 寄存器存储返回给上一级函数

了解堆栈存在的目的和编译器对堆栈使用的规则是理解操作系统一些关键性代码的基础


堆栈寄存器

      -- ebp 基址指针(base pointer),在C语言中用作记录当前函数调用基址
      -- esp 堆栈指针(stack pointer)

堆栈操作

      -- push 栈顶地址减少4个字节(32位)
      -- pop 栈顶地址增加4个字节(32位)

堆栈操作中涉及的其它关键寄存器

      cs : eip  总是指向下一条指令的地址
      -- 顺序执行:总是指向地址连续的下一条指令
      -- 跳转/分支:执行这样的指令的时候,cs:eip的值会根据程序需要被修改
      -- call:将当前cs:eip的值压入栈顶,cs:eip指向被调用函数的入口地址
      -- ret:从栈顶弹出原来保存在这里的cs:eip的值,放入cs:eip
      -- 发生中断时,CPU把寄存器的值压到内核堆栈里,eip指向中断处理程序的入口地址


Stack memory + operations

C语言函数调用堆栈框架_第1张图片
堆栈操作

Stack grows down
Use to implement procedure calls
(* 号表示eip寄存器不能被直接修改,只能通过特殊指令间接修改)



函数调用堆栈框架


C语言函数调用堆栈框架_第2张图片
函数的堆栈框架

call target

      -- 执行call之前
      -- 执行call时,cs:eip原来的值指向call下一条指令,该值被保存到栈顶,然后cs:eip的值指向target的入口地址

进入target(Prologue)

      -- 第一条指令:pushl %ebp
      -- 第二条指令:movl %esp, %ebp
      -- 函数体中的常规操作,可能会压栈、出栈

退出target(Epilogue)

      -- 第一条指令:movl %ebp, %esp
      -- 第二条指令:popl %ebp
      -- ret


Gcc calling conventions

C语言函数调用堆栈框架_第3张图片
Gcc calling conventions

Saved %ebp’s form a chain, can walk stack
Arguments and locals at fixed offsets from EBP


通过反汇编一个简单的C程序,分析汇编代码理解C语言函数调用堆栈框架

C程序

C程序

汇编代码

C语言函数调用堆栈框架_第4张图片
汇编代码


观察另一段小程序

C语言函数调用堆栈框架_第5张图片
一段小程序


观察main中的局部变量

C语言函数调用堆栈框架_第6张图片
观察main中的局部变量


如何传递参数给p2

C语言函数调用堆栈框架_第7张图片
如何传递参数给p2

Q:p2的返回值是如何返回给main的?


观察p2的堆栈框架

C语言函数调用堆栈框架_第8张图片
观察p2的堆栈框架


(完)

你可能感兴趣的:(C语言函数调用堆栈框架)