【发布时间】:2019-12-07 20:28:01
【问题描述】:
/SUBSYSTEM = CONSOLE 链接器选项在此 MS document 的 CONSOLE 部分下进行了描述,如下所示:
Win32 字符模式应用程序。操作系统提供了一个 控制台应用程序的控制台。如果
main或wmain被定义为 本机代码,int main(array<String ^> ^)是为托管定义的 代码,或者您使用/clr:safe完全构建应用程序,CONSOLE是默认值。
因此,我得出结论,默认情况下使用CONSOLE 构建不提供/SUBSYSTEM,但提供/ENTRY = main 或wmain 的程序集(本机代码)。我可以通过下面的代码确认这一点,
.386
.MODEL flat, stdcall
.stack 4096
ExitProcess PROTO STDCALL, dwExitCode: DWORD
.CODE
main PROC
mov eax, -1
invoke ExitProcess, 0
main ENDP
END main
根据 PE 格式文档中的this table,通过对相应的可执行文件运行 DUMPBIN 来获得此输出,这证实了上面的段落。
同样适用于 /SUBSYSTEM = WINDOWS,如 WINDOWS 部分所述,如下所示:
应用程序不需要控制台,可能是因为它创建 它自己的窗口用于与用户交互。如果
WinMain或wWinMain定义为本机代码,或WinMain(HISTANCE *, HINSTANCE *, char *, int)或wWinMain(HINSTANCE *, HINSTANCE *, wchar_t *, int)是为托管代码定义的,WINDOWS是 默认。
但是,当我尝试在没有 /SUBSYSTEM 选项但使用 /ENTRY = WinMain 的情况下构建下面的汇编代码时,链接器会发出以下错误:LNK1221: a subsystem can't be inferred and must be defined。
.386
.MODEL flat, stdcall
.stack 4096
ExitProcess PROTO STDCALL, dwExitCode: DWORD
.CODE
WinMain PROC
mov eax, -1
invoke ExitProcess, 0
WinMain ENDP
END WinMain
然后我必须得出结论,暗示的 Microsoft 文档中存在与 /SUBSYSTEM = Windows 相关的缺陷。还是我错过了什么?
编辑
我介绍了这个编辑部分,以回应下面罗斯里奇给出的答案。
这些是我为所有可能的场景所做的构建模拟
表明/SUBSYSTEM 中以下句子中使用的术语已定义 表示在 /ENTRY 选项中定义,而不是在源文件或 .obj 文件中。
-
控制台小节中的“如果
mainorwmain被定义为本机代码...” - 如果
WinMain或wWinMain定义为本机代码 ..." 在 Windows 小节
提到的 MS 文档。
因此,在我看来,我的第一个示例没有任何问题,只是因为其他案例甚至没有构建。
EDIT1
我仍然不明白为什么我需要擦除 END 指令的入口点。你能解释一下吗?尽管如此,在进行此擦除后,我与您的结果仍有一些差异,如下所示。
令人惊讶的是,您能够构建上面的最后一个案例,我继续遇到链接器错误。
【问题讨论】:
-
整个入口点名称可能只是用于编译器,然后相应地调用链接器。它记录在链接器中,因为我猜它具有这些选项。
-
如果您指定
/SUBSYSTEM=Windows选项,第二个示例是否链接并正确运行? -
@prl 当然可以,
标签: visual-studio assembly linker