gpt4 book ai didi

linux - 谁能解释一些简单的汇编代码?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:31:30 27 4
gpt4 key购买 nike

我刚开始学习汇编。这是 gdb 的转储,用于打印 hello ranjit 的简单程序。

Dump of assembler code for function main:
0x080483b4 <+0>: push %ebp
0x080483b5 <+1>: mov %esp,%ebp
0x080483b7 <+3>: sub $0x4,%esp
=> 0x080483ba <+6>: movl $0x8048490,(%esp)
0x080483c1 <+13>: call 0x80482f0 <puts@plt>
0x080483c6 <+18>: leave
0x080483c7 <+19>: ret

我的问题是:

  1. 为什么每次 ebp 都在程序开始时被压入堆栈?运行此程序所必需的 ebp 中有什么?
  2. 在第二行,为什么 ebp 被复制到 esp?
  3. 我根本听不懂第三行。我对 SUB 语法的了解是“sub dest,source”,但这里如何从 4 中减去 esp 并存储在 4 中?
  4. “$0x8048490”这个值是多少?为什么移到esp,为什么这次把esp括在括号里?它表示与没有括号的 esp 不同的东西吗?
  5. 下一行是对函数的调用,但是这个“0x80482f0”是什么?
  6. 什么是 leave 和 ret(ret 可能意味着返回 lib c.)?

操作系统:ubuntu 10,编译器:gcc

最佳答案

ebp在 Intel 处理器中用作帧指针(假设您使用的是使用帧的调用约定)。

它提供了一个已知的引用点,用于定位传入的参数(一方面)和局部变量(另一方面),无论您在函数处于事件状态时如何使用堆栈指针。

顺序:

push   %ebp       ; save callers frame pointer
mov %esp,%ebp ; create a new frame pointer
sub $N,%esp ; make space for locals

保存前一个堆栈帧(调用者)的帧指针,加载一个新的帧指针,然后调整堆栈以容纳当前“堆栈级别”的内容。

因为参数会在设置框架之前被压入,所以可以用[bp+N]访问它们。其中 N是一个合适的偏移量。

同样,因为局部变量是在帧指针“下”创建的,所以可以用[bp-N] 访问它们。 .

leave指令是撤消该堆栈帧的单个指令。您过去必须手动完成,但英特尔引入了一种更快的完成方式。它在功能上等同于:

mov  %ebp, %esp   ; restore the old stack pointer
pop %ebp ; and frame pointer

(旧的手动方式)。

一个一个地回答问题,以防我遗漏了什么:

  1. 开始一个新的框架。见上文。

  2. 不是。 esp复制到 ebp .这是 AT&T 表示法(%reg 是一个死赠品),其中(除其他外)源和目标操作数相对于 Intel 表示法进行交换。

  3. 请参阅上面 (2) 的答案。您要从 esp 中减去 4 ,而不是相反。

  4. 这是传递给函数的参数 0x80482f0 .它没有被加载到 esp但在 esp 指向的内存中.换句话说,它被压入堆栈。由于被调用的函数是 puts (见下面(5)),就是你要的字符串的地址puts编辑。

  5. <> 中的函数名称地址之后。它正在调用 puts函数(可能是标准库中的函数,但不能保证)。有关 PLT 的说明,请参阅 here .

  6. 我已经解释过了leave上面是在退出前展开当前堆栈帧。 ret简单地从当前函数返回。如果当前函数是 main ,它会回到 C 启动代码。

关于linux - 谁能解释一些简单的汇编代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6435463/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com