美文网首页
函数栈帧与IP寄存器

函数栈帧与IP寄存器

作者: JumpDong | 来源:发表于2024-08-12 11:11 被阅读0次

接着上篇文章内容

函数栈帧与BP寄存器

我们继续构造两个函数的栈帧,GDB调试,当程序在main函数停下时,查看寄存器

image.png

从汇编代码可以看出,执行完foo函数后,回到main函数的返回地址是0x4011e4。

当前的寄存器状态如下

(gdb) info registers rbp
rbp            0x7fffe1de03f0   0x7fffe1de03f0
(gdb) info registers rsp
rsp            0x7fffe1de03e0   0x7fffe1de03e0
(gdb) info registers rip
rip            0x4011da 0x4011da <main+15>
(gdb) 

继续执行程序,在foo函数停下,查看寄存器

image.png

从上篇文章,我们知道,BP寄存器存的地址里存的是main函数的BP地址,那返回地址呢?

在 x86 架构中,返回地址通常占用 4 个字节(32 位系统)或 8 个字节(64 位系统)。这个返回地址存储了函数执行完毕后要返回到的指令地址,用于指示程序继续执行的位置。

  • 32 位系统(x86):返回地址通常占用 4 个字节,因为在 32 位系统中地址空间是 32 位长。

  • 64 位系统(x86-64):返回地址通常占用 8 个字节,因为在 64 位系统中地址空间是 64 位长。

这个返回地址在函数调用时被压入栈中,用于在函数执行完毕后返回到调用位置。当函数执行结束时,程序将从这个返回地址取出地址值,跳转到该地址以继续执行程序。

我们打印rbp+8地址存储的内容,恰好是main函数的返回地址,0x4011e4 <main+25>

(gdb) info registers rbp
rbp            0x7fffe1de03d0   0x7fffe1de03d0
(gdb) x/a 0x7fffe1de03d8
0x7fffe1de03d8: 0x4011e4 <main+25>
(gdb) 

由此,我们可以构造出两个函数的栈帧结构。

这里,我们也可以思考出,函数调用栈的解析过程:

因为当前函数的BP一定在寄存器里,是已知的,然后根据当前函数的BP前后数据可查到上个函数的返回地址和BP,依次类推,可以回溯出所有函数的调用栈。

High Address
          
           +-----------------+ 
           |  上个函数的BP    |  
           +-----------------+ <--- BP (0x7fffe1de03f0)
           |  ...            |
           +-----------------+ <--- SP (0x7fffe1de03e0)
           |  main的返回地址  |  0x4011e4 <main+25>
           +-----------------+ <--- BP + 8 (0x7fffe1de03d8)
           |  main函数的BP    |  0x7fffe1de03f0
           +-----------------+ <--- BP (0x7fffe1de03d0)
           |  b              |
           +-----------------+ <--- BP - 4
           |  c              |
           +-----------------+ <--- BP - 8
           |  a              |
           +-----------------+ <--- BP - c
           |    ...          |
           +-----------------+
           |                 |
           |    未使用的空间   |
           |                 |
           +-----------------+
           
Low Address

相关文章

  • 栈帧与函数调用流程(内存)---- 8086处理器

    栈帧:一个函数执行的环境,一个栈帧代表一个函数 栈帧结构: 一组栈帧寄存器-->SP局部变量bp以前的值-->BP...

  • ARM 读书笔记

    寄存器 内存 和 栈R0-R3 传递参数 与返回值R7 帧指针,指向母函数 与被调用字函数在栈中的交界...

  • 巧用函数栈实现栈的反转

    一、函数栈 函数的调用过程其实就是一个压栈的过程,在函数栈中,每个函数所占空间成为一个 栈帧。栈帧中保存着函数的形...

  • 理解函数的调用过程

    一、函数的范围 ebp寄存器指向函数的栈底,esp寄存器指向函数的栈顶,共同划分了函数的活动范围。减小esp的值相...

  • 宏、普通函数、内联函数之间的区别

    普通函数 调用时向栈中push函数帧,调用结束后pop函数帧。编译器会在函数调用语句的前后,插入入栈和出栈的辅助代...

  • 图解Linux是如何进行函数调用的?

    开篇依旧先提出几个问题: 进程虚拟地址空间是如何分布的? 函数调用的栈帧结构是什么样子? 函数调用涉及到的寄存器都...

  • 5. linux下的栈帧分析

    @toc 1.linux下的栈帧分析2. 栈帧 1. 栈帧 每一次函数的调用,都会在调用栈上维护一个独立的栈帧(s...

  • Python 函数的执行流程-函数递归-匿名函数-生成器

    1 函数的执行流程 函数的执行需要对函数进行压栈的,什么是压栈呢,简而言之就是在函数执行时在栈中创建栈帧存放需要变...

  • C 与汇编程序的约定调用

    1.说明 函数调用时通过栈帧来实现的,栈帧是指为一个单独的函数调用单独分配的那部分栈空间。当运行中的程序调用另一个...

  • 打印函数调用堆栈

    相关函数签名 backtrace():栈回溯,保存各个栈帧的地址。该函数用于获取当前线程的函数调用堆栈,获取的信息...

网友评论

      本文标题:函数栈帧与IP寄存器

      本文链接:https://www.haomeiwen.com/subject/extdkjtx.html