如果我使用 Win32 入口点,我应该增加 esp 值以从堆栈中删除变量吗?

If I am using the Win32 entry point, should I increase the esp value to remove the variables from the stack?

如果我使用的是 Win32 入口点并且我有以下代码(在 NASM 中):

extern _ExitProcess@4

global _start

section .text
_start:
    mov ebp, esp

    ; Reserve space onto the stack for two 4 bytes variables
    sub esp, 4
    sub esp, 4

    ; ExitProcess(0)
    push 0
    call _ExitProcess@4

现在,在退出进程之前,我是否应该增加 esp 值以从堆栈中删除两个变量,就像我对任何 "normal" 函数所做的那样?

ExitProcess api 可以从任何地方调用。在任何功能和子功能中。和堆栈指针当然可以是任何。您不需要将任何寄存器(包括堆栈指针)设置为某些(以及哪些?)值。所以回答 - 你不需要增加 esp


如@HarryJohnston 所述,堆栈当然必须有效且对齐。与 any api 调用之前一样。 ExiProcess 通常是 api。并且可以像其他任何人一样被调用 api。和任何其他 api 一样,它只需要有效的堆栈而不需要具体的堆栈指针值。非易失性寄存器只需要将我们return恢复到调用者。但 ExiProcess 不是 return 给来电者。从来没有 return

所以规则非常简单 - 如果你 return 来自任何函数(入口点或绝对任意 - 无关紧要) - 我们需要恢复非易失性寄存器(堆栈指针 esprsp 基于调用约定)和 return。如果我们不 return 调用者 - 我们不需要 restore/preserve 任何寄存器。如果我们 return 从线程或进程入口点,尽管有良好的实践也恢复所有寄存器 - 在当前 windows 实现中 - 即使我们不这样做,任何方式都可以工作,因为 kernel32 shell 调用者只需在我们 return 之后调用 ExitThread。它在这里不使用任何非易失性寄存器或局部变量。所以即使不从入口点恢复它,代码也能正常工作,但最好还是恢复它