【问题标题】:Is it the program or the OS that is responsible for setting up the stack是程序还是操作系统负责设置堆栈
【发布时间】:2010-07-16 13:02:22
【问题描述】:

问这个问题是因为作者正在构建一个编译器(src -> asm),并且正在编写用于生成汇编代码的代码。

当程序在基于 Linux(实际上是任何操作系统)的操作系统上执行时,首先发生的事情之一是堆栈被设置,并且 SP 寄存器被分配了堆栈开头的内存地址。

我很好奇执行上述操作的责任在于程序还是操作系统本身。如果是程序的责任,程序是如何完成的(特别是在Linux基础环境中)?

单个程序必须执行哪些其他操作才能开始执行其主要功能?

感谢带有注释的 i386 NASM 汇编代码的示例。此外,任何可以帮助作者实现目标的网络资源也将不胜感激。

【问题讨论】:

  • 这位评论员想知道为什么作者用第三人称谈论自己。
  • 我简单的头脑无法处理手动内存管理而不意外跨越几个突触'。肯定有副作用的,呵呵。

标签: linux assembly


【解决方案1】:

你可以去搜索关于 linux 的 ELF 格式。 以及用于 windows 的 PE-COFF。

这些是可执行文件的格式,这是操作系统知道的。 在 Linux 下,您有负责加载程序的模块,并且在其他模块中使用可执行格式来正确加载程序。

编辑:来自 glibc 的线索给出答案:

/*
[snip]
%esp        The stack contains the arguments and environment:
        0(%esp)         argc
        4(%esp)         argv[0]
        ...
        (4*argc)(%esp)      NULL
        (4*(argc+1))(%esp)  envp[0]
        ...
                    NULL
[snip]
*/
[snip]
_start:
    /* Clear the frame pointer.  The ABI suggests this be done, to mark
       the outermost frame obviously.  */
    xorl %ebp, %ebp

    /* Extract the arguments as encoded on the stack and set up
       the arguments for `main': argc, argv.  envp will be determined
       later in __libc_start_main.  */
    popl %esi       /* Pop the argument count.  */
    movl %esp, %ecx     /* argv starts just at the current stack top.*/

    /* Before pushing the arguments align the stack to a 16-byte
    (SSE needs 16-byte alignment) boundary to avoid penalties from
    misaligned accesses.  Thanks to Edward Seidl <seidl@janed.com>
    for pointing this out.  */
    andl $0xfffffff0, %esp
    pushl %eax      /* Push garbage because we allocate
                   28 more bytes.  */

    /* Provide the highest stack address to the user code (for stacks
       which grow downwards).  */
    pushl %esp

    pushl %edx      /* Push address of the shared library
                   termination function.  */

[snip]

【讨论】:

    【解决方案2】:

    操作系统将为您设置 SP 并将程序参数放在堆栈上。您的程序无需进行任何特殊设置即可运行。

    至于程序启动时Linux上的实际堆栈布局,您可以查看this document了解详情。

    【讨论】:

      【解决方案3】:

      操作系统的程序加载器负责将堆栈空间分配给可执行进程。堆栈只是加载程序在将程序加载到 RAM 中执行时修复的一个内存段(查看您的链接映射)。其他段包括未初始化内存和已初始化内存。加载器也称为“可重定位”加载器,表示它负责将程序加载到内存中方便的位置。

      为嵌入式系统进行交叉编译/链接时,链接规范包含在加载时使用的堆和堆栈信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-05-27
        • 1970-01-01
        • 2012-05-04
        • 2011-09-07
        • 2020-09-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多