linux - 了解 C 程序中的汇编语言 _start 标签

标签 linux gcc assembly x86 glibc

我写了一个简单的 c 程序,并尝试使用 GDB 来调试程序。我了解在主要功能中使用以下内容:

进入时

push   %ebp
mov    %esp,%ebp

退出时

leave
ret

然后我在 _start 上尝试了 gdb,我得到了以下内容

xor    %ebp,%ebp
pop    %esi
mov    %esp,%ecx
and    $0xfffffff0,%esp
push   %eax
push   %esp
push   %edx
push   $0x80484d0
push   $0x8048470
push   %ecx
push   %esi
push   $0x8048414
call   0x8048328 <__libc_start_main@plt>
hlt
nop
nop
nop
nop

我无法理解这些台词及其背后的逻辑。

有人可以提供任何指导来帮助解释 _start 的代码吗?

最佳答案

这是评论很好的 assembly source您发布的代码。

总结起来,它做了以下事情:

  1. 建立一个 ebp = 0 的哨兵栈帧,这样遍历栈的代码可以很容易地找到它的终点
  2. 将命令行参数的数量弹出到 esi 中,以便我们可以将它们传递给 __libc_start_main
  3. 将堆栈指针对齐到 16 位的倍数以符合 ABI。在某些 Linux 版本中不能保证会出现这种情况,因此必须手动完成以防万一。
  4. __libc_csu_fini__libc_csu_init 的地址、参数向量、参数个数和main 的地址作为参数推送到 __libc_start_main
  5. __libc_start_main 被调用。此函数(源代码 here)设置一些 glibc 内部变量并最终调用 main。它永远不会回来。
  6. 如果由于任何原因 __libc_start_main 应该返回,则在之后放置一条 hlt 指令。该指令在用户代码中是不允许的,应该会导致程序崩溃(希望如此)。
  7. nop 指令的最后一系列是由汇编程序插入的填充,因此下一个函数从 16 字节的倍数开始以获得更好的性能。它在正常执行中永远不会达到。

关于linux - 了解 C 程序中的汇编语言 _start 标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35519417/

相关文章:

python - 同时发送消息python脚本

c - 哪个变量存储了 gcc 中 C GENERIC AST 的根节点?

c - 无法从 Linux 中的 C 访问程序集的正确全局标签数据

c - 如何将汇编代码转换为 C 语言?

c++ - 为什么在两个不同的类中调用 TinyXPath 时,同一对象会给出不同的结果?

linux - Linux 中的无缓冲 I/O

c - 叉+管问题

c - GCC 按位属性

c++ - 如何使用 `static linking` 和 `Dynamic linking` 以及 gcc 和 Visual Studio 构建 C/C++ 程序?

java - 如何从java调用用汇编语言代码编写的函数?