是程序还是操作系统负责设置堆栈

时间:2010-07-16 13:02:22

标签: linux assembly

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

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

我很好奇上面这样做的责任在于程序还是操作系统本身。如果责任在于程序,那么程序如何实现(特别是在Linux基础环境中)?

个别程序在开始执行其主要功能之前必须执行哪些其他操作?

评论i386 NASM汇编代码的示例表示赞赏。此外,任何可以帮助作者实现其目标的网络资源也将非常受欢迎。

3 个答案:

答案 0 :(得分:2)

您可以搜索有关Linux的ELF格式。 和PE-COFF for windows。

这些是可执行文件的格式,它是操作系统所知道的。 在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]

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

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