x64 似乎不像 x86 那样接受 END 指令中的入口点。这种语法变化有什么具体原因吗?

x64 doesn't seem to accept an entry point in the END directive as x86 does. Was there any specific reason for this change in the syntax?

根据 GitHub 中的 MS documentation it appears that x86 and x64 assemblies have the same syntax as regards the END directive, i.e., that both accept an optionally entry point [address] with this directive. But given this issue,x64 似乎不接受此选项。下面的示例显示了这一点:

EXTERN ExitProcess:PROC
.CODE
main PROC
    mov eax, 10
exit:
    xor ecx, ecx
    call ExitProcess
main ENDP
END main

在 VS2017 中产生以下错误消息:

error A2008: syntax error : main
error A2088: END directive required at end of file

恕我直言,这些错误消息非常混乱,特别是第二条,似乎说代码中没有 END 指令。

但假设 GitHub 中的问题是正确的,我想知道从 x86 到 x64 的语法更改是否有任何特定原因。

不幸的是,对于 x64 版本的 MASM,这是未记录的行为。在这个版本的汇编器上,END 指令不接受入口点符号。您必须简单地以 "END" 语句结束您的源代码。 (使 END 指令完全无用,因为从 MS-DOS 2.0 开始就不需要它来标记文件的结尾了。)

作为解决方法,您可以使用 /ENTRY 链接器选项指定入口点,您可以在项目的 属性 页面下的 Visual Studio IDE 中设置该选项-> 链接器 -> 高级 -> 入口点。您还可以重命名入口点以依赖链接器的默认入口点,这取决于所使用的子系统,如 Microsoft 的 /ENTRY 文档所述:

By default, the starting address is a function name from the C run-time library. The linker selects it according to the attributes of the program, as shown in the following table.
Function name                                 Default for 

mainCRTStartup (or wmainCRTStartup)           An application that uses /SUBSYSTEM:CONSOLE;
                                              calls main (or wmain) 
WinMainCRTStartup (or wWinMainCRTStartup)     An application that uses /SUBSYSTEM:WINDOWS; 
                                              calls WinMain (or wWinMain), which must be
                                              defined to use __stdcall 
_DllMainCRTStartup                            A DLL; calls DllMain if it exists, which must
                                              be defined to use __stdcall 
If the /DLL or /SUBSYSTEM option is not specified, the linker selects a subsystem and entry point depending on whether main or WinMain is defined.

如果您真的想在程序集文件本身中指定入口点,那么您可以使用 32 位 x86 版本的 MASM 用来通知链接器的相同方法:在.drectve 节。像这样:

_DRECTVE SEGMENT INFO ALIAS(".drectve")
    DB  " /ENTRY:main "
_DRECTVE ENDS

注意选项周围的空格。