Win32入口点是否需要保留任何寄存器值(被调用者保存的寄存器)?

5

我正在使用NASM编写一个程序,不想将其与CRT进行链接,因此我会指定入口点(这将是Win32入口点)。以下是程序源代码:

global _myEntryPoint

section .text
_myEntryPoint:
    mov eax, 12345

现在我对Win32入口点的了解是(如果我错了,请纠正我):

  • Win32入口点不像普通函数一样返回一个值(为了退出Win32入口点,我必须调用ExitProcess())。
  • Win32入口点不接受任何参数。

现在我不知道的是:

  • Win32入口点是否需要保留任何寄存器的值(被调用者保存的寄存器)?我认为答案是不需要,因为当Win32入口点退出时,它会终止进程而不是将执行返回给期望保留某些寄存器值的函数。

WinMain只是Win32进程入口点的传统名称。 - IInspectable
1
可能是为什么在Win32下使用RET时需要ExitProcess?的重复问题。 - Harry Johnston
这并不是真正的重复。它解释了从入口点返回的后果,并得出结论,没有任何好的理由这样做。它没有解释如果选择从入口点返回时要保留哪些寄存器(以及哪些寄存器)。我不确定原帖作者是否真的需要知道,但这就是问题所在。 - IInspectable
@IInspectable,当时我认为这可能会消除一些困惑——OP陈述了一个前提,即您不能从入口点返回,但随后又问您是否需要保留寄存器,这实际上并不合理。但现在我想你是对的。我将撤回关闭投票。 - Harry Johnston
入口点只是一个函数。如果我们直接调用 ExitProcess,无论是否保存寄存器都没有关系。如果我们返回,则需要像任何常规函数一样保存/恢复寄存器 - 在 x86 中为 ebx、ebp、edi、esi、esp,在 amd64 中为 rbx、rbp、rdi、rsi、rsp、r12-r15 - RbMm
一个APC从LdrInitializeThunk开始,它传递了一个线程上下文以在初始化后恢复。上下文具有可执行文件的入口点和初始线程参数,以及初始线程的PEB指针。上下文在RtlUserThreadStart处恢复,对于Windows应用程序,它调用BaseThreadInitThunk,然后调用指定的入口点。PEB指针参数通常被忽略。在RtlExitUserProcess中,加载器重新获得控制权以关闭进程,然后进程被终止。 - Eryk Sun
1个回答

7

我对提出的重复问题的回答中所述,你根本不应该从Win32入口点返回,因此显然没有必要保留任何寄存器。你的问题表达方式含糊地暗示你担心在调用ExitProcess之前需要恢复寄存器,但实际上并非如此;调用ExitProcess不会导致你从入口点返回,它只是停止运行你的代码。(另请参阅这里进行更新,以及这也可能会引起你的兴趣。)

如果你忽略了这个建议,仍然从入口点返回,那么实际上答案是一样的:你并不需要保留任何寄存器。据我所知,这种行为没有记录在案,但是如果你想谨慎起见,可能最好严格遵循 stdcall 约定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接