函数调用时发生了什么 :
系统在调用函数时,会为它开辟一个新的栈侦,并把新的栈侦压入系统栈中,这个新的栈侦中的内存空间会被它所属的函数独占!
例如:
(1) main() 函数在调用函数 A() 时,首先在自己的栈侦中压入函数返回地址,然后为函数 A() 创建新的栈侦并压入系统栈
(2) 函数 A() 执行完返回时,函数 A() 的栈侦会被弹出系统栈 , main() 函数栈侦中的返回地址会被 "披露" 在栈顶,此时处理器按照这个返回地址跳转到 main 函数代码区执行
寄存器和函数栈侦 :
正在运行的函数栈侦总是在系统栈的栈顶
ESP : 栈指针寄存器,其内存放着一个指针,该指针永远指向系统栈最上面一个栈侦的栈顶
EBP : 栈指针寄存器,其内存放着一个指针,该指针永远指向系统栈最上面一个栈侦的栈底
EIP : 指令寄存器 , 其内存放着一个指针, 该指针永远指向下一条等待执行的指令地址
函数栈侦 : ESP 和 EBP 之间的内存空间为当前函数栈侦
函数栈侦中包含的信息 如下
(1) 局部变量 : 为函数局部变量开辟的内存空间
(2) 栈侦状态值 : 保存前栈侦的顶部和底部,用于在本栈被弹出后恢复出上一个栈侦
(3) 函数返回地址 : 保存当前函数调用前的 "断点" 信息,也就是函数调用前的指令位置,以便在函数返回时能够恢复到函数被调用前的代码区中继续执行命令
函数调用大致几个步骤 :
(1) 参数入栈 : 将参数从右向左依次压入系统堆栈
(2) 返回地址入栈 : 将当前代码区调用指令的下一条指令地址压入栈中 , 供函数返回时继续执行
(3) 代码区跳转 : 处理器从当前代码区跳转到被调用函数的入口处
(4) 栈侦调整 :