Windows 上有几种类型的应用程序,根据它们的类型,它们具有不同的入口点。通过 link.exe 选项:
/SUBSYSTEM:CONSOLE
- 需要main
并与msvcrXX.dll
. 这些应用程序在控制台窗口中运行;如果您没有运行 cmd.exe 的实例,则会打开一个。
/SUBSYSTEM:WINDOWS
-WinMain
是起点。见这里。通常在 C 中,这些#include <windows.h>
和 直接链接到kernel32.dll
. 这些是一个 gui 应用程序,几乎可以肯定地与这些应用程序相关user32.dll
联advapi32.dll
。
/SUBSYSTEM:NATIVE
- 这里有两种类型的应用程序;驱动程序和应用程序。本机 NT 应用程序在 Windows 启动期间运行,并且需要NtProcessSStartup
作为入口点。本机应用程序中没有 libc。驱动程序再次不同。
此处link.exe
提供了支持的 Windows 子系统的完整列表。
_start
是符号窗口实际上会启动您的代码运行。通常,libc
或类似的东西实际上会处理_start
并执行一些初始设置,因此您的程序实际上并没有完全从_main
. 如果你想与libc
你链接会有问题,因为你会有与 libc 库冲突的符号。但是,如果您从不打算调用属于 C 或 C++ 标准库的任何函数,则可以使用_start
.
编辑哎呀我刚刚注意到这一点:
; how to compile: nasm -f elf test.asm
; how to link: ld -o test.exe test.o
我假设你没有使用那个-f elf
。ELF(executable and linkable format)是linux的可执行文件格式;Windows 需要可移植可执行 (PE) 映像。nasm 选项是-f win32
, 或用于 dos nasm -f coff
。
编辑 2只是为了检查,我组装了代码并再次反汇编它。我也用过mingw。无论如何,我得到了:
SECTION .text align=16 execute ; section number 1, code
Entry_point:; Function begin
; Note: Length-changing prefix causes delay on Intel processors
mov ax, 4 ; 00401000 _ 66: B8, 0004
?_001: jmp ?_001 ; 00401004 _ EB, FE
; Entry_point End of function
; Note: Length-changing prefix causes delay on Intel processors
mov ax, 4 ; 00401006 _ 66: B8, 0004
?_002: jmp ?_002 ; 0040100A _ EB, FE
标头的其余部分似乎是没有入口点规范的有效 PE 格式可执行文件。因此,我相信代码只是“落入”第一段汇编代码开始。我不建议这种行为,尤其是在链接多个对象时,因为我不知道会发生什么。使用-entry
.
反汇编精灵目标文件我得到这个:
SECTION .data align=4 noexecute ; section number 1, data
SECTION .text align=16 execute ; section number 2, code
_start_here:; Local function
; Note: Length-changing prefix causes delay on Intel processors
mov ax, 4 ; 0000 _ 66: B8, 0004
?_001: jmp ?_001 ; 0004 _ EB, FE
_another_symbol:; Local function
; Note: Length-changing prefix causes delay on Intel processors
mov ax, 4 ; 0006 _ 66: B8, 0004
?_002: jmp ?_002
换句话说,其中没有任何特定的 ELF 格式标头。我相信您对此很幸运;开始导入或尝试与其他代码模块链接,事情将开始变得更加棘手。
对于 Windows / mingw,您需要:
nasm -f win32 file.asm
对于您要组装的每个文件。需要win32
时win64
更换。ld
可以很好地链接。
只是一个想法-我从未解释过这@16
部分。这些函数在 Windows 上是 16 字节对齐的,而如您所见,数据仅是 4 字节对齐的。有关原因,请参阅此说明。