该程序中的堆栈指针如何通过 call 和 ret 更改

2023-12-07

我的问题涉及当上下文发生变化时,尤其是关于RSP and RBP.

鉴于这个非常简单的程序:

Reading symbols from ./function_call...done.
(gdb) disass main
Dump of assembler code for function main:
   0x00000000004004d6 <+0>: push   rbp
   0x00000000004004d7 <+1>: mov    rbp,rsp
   0x00000000004004da <+4>: mov    esi,0x2
   0x00000000004004df <+9>: mov    edi,0x1
   0x00000000004004e4 <+14>:    call   0x4004b6 <add_and_7>
   0x00000000004004e9 <+19>:    mov    eax,0x0
   0x00000000004004ee <+24>:    pop    rbp
   0x00000000004004ef <+25>:    ret    
End of assembler dump.
(gdb) disass add_and_7
Dump of assembler code for function add_and_7:
   0x00000000004004b6 <+0>: push   rbp
   0x00000000004004b7 <+1>: mov    rbp,rsp
   0x00000000004004ba <+4>: mov    DWORD PTR [rbp-0x14],edi
   0x00000000004004bd <+7>: mov    DWORD PTR [rbp-0x18],esi
   0x00000000004004c0 <+10>:    mov    DWORD PTR [rbp-0x4],0x7
   0x00000000004004c7 <+17>:    mov    edx,DWORD PTR [rbp-0x14]
   0x00000000004004ca <+20>:    mov    eax,DWORD PTR [rbp-0x18]
   0x00000000004004cd <+23>:    add    edx,eax
   0x00000000004004cf <+25>:    mov    eax,DWORD PTR [rbp-0x4]
   0x00000000004004d2 <+28>:    add    eax,edx
   0x00000000004004d4 <+30>:    pop    rbp
   0x00000000004004d5 <+31>:    ret    
End of assembler dump.
(gdb) list
1   int add_and_7( int num1, int num2 ) {
2       int seven = 7;
3       return num1 + num2 + seven;
4   }
5   
6   int main() {
7       add_and_7( 1, 2 );
8       return 0;
9   }

所有功能都是从push开始的rbp据我所知,它将父上下文保留到堆栈上。父函数如何知道如何重建自身?是否内置了必要的步骤call and ret?

然后rsp总是被移动到rbp。正如我所读到的,这将新的堆栈基数设置在当前函数的上下文中。我似乎无法弄清楚堆栈指针何时或如何设置到该点。我最好的猜测是汇编函数调用会执行此操作,这是发生的事情吗?

最后,当一个方法返回时,看起来像eax是用于父函数利用其子函数的返回的寄存器。是eax明确用于此目的还是这只是我的编译器和体系结构的约定?


父函数如何知道如何重建自身? call 和 ret 中是否内置了必要的步骤?

在调用函数之前,会保存寄存器的当前状态以及返回地址。call指令跳转到被调用函数开始的特定地址。返回地址被压入堆栈。当被调用函数返回时,ret指令弹出先前推送的返回地址并转到该位置。

然后rsp总是移动到rbp

rbp 之前被压入堆栈,以便能够从调用者的函数中恢复 rbp 的值。然后,rsp 被移动到 rbp 来为被调用函数创建一个新的堆栈帧。新的基指针已经设置。所以目前rbp和rsp指向相同的地址。如果还有其他push指令,esp自动调整。当函数完成时,pop ebp指令恢复先前压入的堆栈基指针地址。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

该程序中的堆栈指针如何通过 call 和 ret 更改 的相关文章

  • 在汇编中使用 printf 会导致管道传输时输出为空,但可以在终端上使用

    无输出 https stackoverflow com questions 54507957 printf call from assembly do not print to stdout即使在终端上 当输出不包含换行符时也有相同的原因
  • 在汇编中,指令指定数据类型吗?

    我是汇编语言编程 x86 的初学者 以下说法是否正确 在汇编中 BYTE WORD DWORD 等数据类型分别表示 8 位 16 位和 32 位模式 而不仅仅是整数 它们本身没有意义 它们只是位模式 使用它们的指令赋予了它们意义 汇编 代码
  • 调用 printf 系统子例程在汇编代码中输出整数错误[重复]

    这个问题在这里已经有答案了 来回 在windows7控制台窗口中运行gcc s2 asm 然后生成一个exe文件 运行a exe 然后崩溃 为什么 s2 asm 代码由以下源代码生成 int m m 1 iprint m s2 asm请参考
  • 就分页分段内存而言的程序寿命

    我对 x86 Linux 机器中的分段和分页过程有一个令人困惑的概念 如果有人能澄清从开始到结束所涉及的所有步骤 我们将很高兴 x86 使用分页分段内存技术进行内存管理 任何人都可以解释一下从可执行的 elf 格式文件从硬盘加载到主内存到它
  • 将 AT&T 语法转换为 INTEL 语法

    我发现这个 GAS 文件包含一些可以从 CD 启动的引导加载程序代码 我想研究它并尝试制作我自己的一个 但唯一的问题是它采用 AT T 语法而不是 Intel 语法 我对 AT T 语法一无所知 我尝试过使用 Intel2gas 转换器 但
  • 汇编PC相对寻址模式

    我正在研究数据路径 并一直在尝试理解分支指令 这就是我的理解 在 MIPS 中 每条指令都是 32 位 这是 4 个字节 所以下一条指令将是四个字节之外 举个例子 我说PC地址是128 我的第一个问题是理解这个128意味着什么 我目前的信念
  • 函数地址不是实际代码地址

    在 Visual Studio 2008 C 中调试一些代码时 我注意到函数指针变量中的地址不是函数本身的实际地址 这是一个外部 C 函数 int main void printaddr const char print debug sho
  • 在 OllyDbg 和 Assembler 中,EBP+8 是什么意思?

    我正在学习 OllyDbg 中的汇编和调试技巧 以便学习如何使用未记录的函数 现在我遇到以下问题 我有以下代码部分 来自 OllyDbg MOV EDI EDI PUSH EBP MOV EBP ESP MOV EAX DWORD PTR
  • 3 操作数 imul 指令在 ia-32 汇编中到底起什么作用?

    我正在阅读说明 imul 0xffffffd4 ebp ebx 4 eax 我对它到底在做什么感到困惑 我明白那个imul乘法 但我无法弄清楚语法 我知道并且更喜欢 Intel MASM 语法 所以我将使用它 请注意 操作数的顺序在 AT
  • 解释一下 AF 标志在 x86 指令中如何工作?

    我有一个小型 8086 模拟器 并且我已经有一个长期存在的错误了大约 2 年 因为 AF 在 sub 和 add 指令内无法正常运行 我当前计算其值的方法是 8 位数字和减法 uint8 t base subt base base 0xF
  • 了解近调用指令编码

    通过反汇编一些二进制代码 我发现了近调用指令call 0x8ae编码为e8 97 08 00 00 查看指令集参考 我发现这些指令被编码为 call XX XX XX XX lt gt e8 XX XX XX XX being XX XX
  • execve() 无法启动 C 程序

    我正在尝试使用生成一个新进程execve from unistd h在 Linux 上 我尝试向它传递以下参数execve bin ls bin ls NULL 但没有得到结果 我也没有收到错误 程序只是退出 发生这种情况有原因吗 我尝试以
  • 最佳 SSE 无符号 8 位比较

    我试图找到使用 SSE 最高 SSE 4 2 执行 8 位无符号比较的最佳方法 我正在处理的最常见情况是比较 gt 0U 例如 mm cmpgt epu8 v mm setzero si128 1 当然 这也可以被认为是对非零的简单测试 但
  • 如何将 4 位十六进制转换为 7 位 ASCII?

    作业是通过编写一个可以在 4 位十六进制和 7 位 ASCII 之间转换的子程序来学习汇编编程 起初我不知道 但经过一些研究后 我可以做出努力并绘制流程图并制作程序 但它并不完全正确 所以我请求您的指导来帮助我解决这个问题 实际的作业文本是
  • 为什么 gcc 会在显然不需要的时候生成 PLT?

    考虑这段代码 int foo int main foo while 1 int foo 在共享对象中实现 编译此代码gcc o main main c lfoo nostdlib m32 O2 e main no pic L shared给
  • 返回中断处理程序后程序计数器去了哪里?

    您好 我想知道当程序从中断服务程序返回时程序计数器去哪里 我知道当中断事件发生时PC被压入堆栈 但是下一个或同一个 刚刚执行的一个 被压入堆栈的地址是什么 当我们有 first instruction interrupt event her
  • 如何在 gdb 中给定地址处的汇编指令上中断?

    0x0000000000400448
  • 如何配置和采样英特尔进程内性能计数器

    简而言之 我试图在用户级基准测试进程中实现以下目标 伪代码 假设 x86 64 和 UNIX 系统 results for iteration 0 iteration lt num iterations iteration pctr sta
  • 了解使用内存源操作数和 x87 fcomi / fcmov 的 GCC 内联汇编代码

    我正在阅读研究论文Privado 实用且安全的 DNN 推理 用于隐藏依赖于输入的分支 https arxiv org pdf 1810 00602 pdf 我试图理解该论文中的以下 GCC 汇编代码 float temp asm vola
  • 32 位 x86 汇编中堆栈对齐的职责

    我试图清楚地了解谁 调用者或被调用者 负责堆栈对齐 64 位汇编的情况相当清楚 它是由caller 请参阅系统 V AMD64 ABI 第 3 2 2 节栈帧 输入参数区域的末尾应按 16 对齐 32 如果 m256 在堆栈 字节边界上传递

随机推荐

  • cellDoubleClicked 文本 python

    我在使用 PyQt5 时遇到一个问题 我已经制作了一个 QTableWidget 它显示我之前在 pandas 中制作的 DataFrame 来自电子表格 我尝试做的不成功的事情是 从用户双击的单元格中获取文本 以便我可以使用该信息根据所做
  • 所有图像加载后如何发出警报?

    我正在构建一个 JavaScript 游戏 我想在加载所有图像后发出警报 我尝试了这段代码 但它不起作用 function loadEveryThing var imgNumber 0 img1 new Image img1 src 1 p
  • “#”附近的语法不正确。带有 SQL 数据库的 VB.net

    我正在尝试使用以下代码获取日期 今天的 Max 字段 Dim todaydate Format Today Date dd MM yyyy Dim sql1 As String Select max snum From tblbill wh
  • JButton 在鼠标悬停之前不可见

    我正在为我的项目创建一个图形用户界面 当 gui 首次加载时 只有背景可见 因此按钮不可见 但当鼠标悬停在按钮上时 它们是可见的 解决这个问题的办法是什么 public class Home extends JFrame New JPane
  • 在 Scala 中将嵌套案例类转换为嵌套映射

    我有两个嵌套案例类 case class InnerClass param1 String param2 String case class OuterClass myInt Int myInner InnerClass val x Out
  • Azure表存储存储多种类型

    对于以下场景 您有什么建议 我有一个名为 Users 的天蓝色表 其中列如下 首要的关键 RowKey 时间戳 名 LastName Email Phone 然后每个用户都有不同类型的任务 我们将它们称为TaskType1 和TaskTyp
  • jQuery:如果单击链接则添加类

    我在链接中调用 jquery 函数 onclick 例如 a class active href Content 1 a a href Content 2 a a href Content 3 a 正如您所看到的 第一个链接默认具有 act
  • 词形还原java [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我正在寻找一个词形还原Java 中英语的实现 我已经找到了一些 但我需要一些不需要太多内存来运行的东西 顶部 1 GB 谢谢 我不需要词干分析器 T
  • 在 webGL 中渲染 NURBS 曲面

    我需要一些有关在 webGL 中渲染 NURBS 曲面的帮助 几天前 我们的教授指派我们用 NURBS 绘制一面旗帜并为其制作动画 我们必须使用 webGL 并且不能使用 trhee js 我不知道如何继续 尽管我或多或少了解 NURBS
  • 将列表转换为集合会改变元素的顺序吗?

    当我做类似的事情时 U 1 0 0 0 0 0 1 0 set U 它给了我 0 0 1 0 1 0 0 0 我只想将列表转换为集合 有什么帮助吗 Thanks 套装未订购 字典也没有排序 如果您想保留特定顺序 请使用列表 gt gt gt
  • 是否有任何实际理由对 JSON 键使用带引号的字符串?

    根据克罗克福德的说法json org 一个 JSONobject由 制成由 做成members 它由pairs 每对都是由一个string and a value 有一个string被定义为 字符串是零个或多个的序列 Unicode 字符
  • Logstash 中的 JSON 解析器忽略数据?

    我已经这样做有一段时间了 我觉得 Logstash 中的 JSON 过滤器正在为我删除数据 我最初遵循的教程来自https www digitalocean com community tutorials how to install el
  • 具有基本身份验证的 jQuery AJAX 跨域

    我正在尝试通过将数据拉入网页来利用 Beanstalk beanstalkapp com API 以便人们无需访问我的 SVN 即可查看它 我正在尝试通过 jQuery 使用 AJAX 请求来访问它 代码如下 但每次都会出错 并且无法返回数
  • 如何将javascript变量值传递给php变量?

    这是我的 JavaScript 代码 我的html代码
  • 使用 Java 8 动态创建具有复合键的映射

    我想创建一个如下所示的地图 gt Map
  • 对 Google Drive 的 Python 请求

    我正在尝试使用 python requests 库将文件发送到 Google Drive api 我唯一需要它根据谷歌文档发送多部分请求https developers google com drive web manage uploads
  • TypeScript - 将类存储为映射值?

    我的课很少 Test 课程延伸FrameModel 我如何创建地图string的子类FrameModel import FrameModel from FrameModel import TestShipModel from TestGen
  • Android NDK:如何链接多个第三方库

    假设我们正在构建一个共享库 A 它需要链接到 2 个外部静态库 B 和 C 您所拥有的只是 libB a 和 libC a 以及它们的头文件 这是 libA 的简化 Android mk LOCAL LDLIBS external libB
  • 在 mysqli 准备好的语句中使用数组:`WHERE .. IN(..)`查询[重复]

    这个问题在这里已经有答案了 假设我们有一个查询 SELECT FROM somewhere WHERE id IN 1 5 18 25 ORDER BY name 以及要获取的 ID 数组 ids array 1 5 18 25 有了准备好
  • 该程序中的堆栈指针如何通过 call 和 ret 更改

    我的问题涉及当上下文发生变化时 尤其是关于RSP and RBP 鉴于这个非常简单的程序 Reading symbols from function call done gdb disass main Dump of assembler c