在 Windows XP 中使用 NASM 进行编程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6461501/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
programming with NASM in Windows XP
提问by TheFuzz
I have the following code which assembles and runs fine on Windows XP 32 bit, 2.09.08 NASM:
我有以下代码可以在 Windows XP 32 位 2.09.08 NASM 上正常组装和运行:
; how to compile: nasm -f elf test.asm
; how to link: ld -o test.exe test.o
section .data
section .text
;global _WinMain@16
;_WinMain@16:
;global _start
_start:
mov ax,4
jmp $
According to many tutorials on NASM the asm file needs the following in it:
根据许多关于 NASM 的教程,asm 文件需要包含以下内容:
global _WinMain@16
_WinMain@16:
...
As you can see my asm file doesn't have that in it. (it's commented out, All it has is _start). So what is with all of these tutorials mentioning the need for the global _WinMain@16 stuff when my assembly program doesn't have that and works?
正如你所看到的,我的 asm 文件中没有那个。(它被注释掉了,它只有_start)。那么,当我的汇编程序没有全局 _WinMain@16 内容并且可以运行时,所有这些教程都提到了它的必要性吗?
this is the command to assemble: nasm -f elf test.asm
this is the command to link: ld -o test.exe test.o
这是组装命令:nasm -f elf test.asm
这是链接命令:ld -o test.exe test.o
回答by
There are several types of application on Windows with different entry points depending on which type they are. By link.exe option:
Windows 上有多种类型的应用程序,它们具有不同的入口点,具体取决于它们的类型。通过link.exe选项:
/SUBSYSTEM:CONSOLE
- requiresmain
and linking withmsvcrXX.dll
. These applications run in console windows; if you aren't running an instance of cmd.exe, one will be opened./SUBSYSTEM:WINDOWS
-WinMain
is the starting point. See here. Usually in C, these#include <windows.h>
and are linked directly tokernel32.dll
. These a gui apps and are almost definitely linked withuser32.dll
and possiblyadvapi32.dll
as well./SUBSYSTEM:NATIVE
- there are two types of application here; drivers and applications. Native NT apps run during windows startup and requireNtProcessSStartup
as an entry point. There is no libc in native applications. Drivers are different again.
/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。驱动程序又不同了。
A full list of supported windows subsystems by link.exe
is available here.
此处link.exe
提供了受支持的 Windows 子系统的完整列表。
_start
is the symbol windows will actually start your code running at. Normally, libc
or the like actually handles _start
and does some initial setup, so your program doesn't actually quite start at _main
. If you wanted to link with libc
you would have problems, since you'd have conflicting symbols with the libc library. If however you never intend to call any functions that are part of the C or C++ standard libraries, you are ok using _start
.
_start
是符号窗口将实际启动您的代码运行。通常,libc
或类似的实际上处理_start
并进行一些初始设置,因此您的程序实际上并不完全从_main
. 如果您想与libc
您链接,则会遇到问题,因为您会与 libc 库产生冲突的符号。但是,如果您从不打算调用属于 C 或 C++ 标准库的任何函数,则可以使用_start
.
Edityikes I've just noticed this:
编辑yikes 我刚刚注意到这一点:
; how to compile: nasm -f elf test.asm
; how to link: ld -o test.exe test.o
I assume you're not using the -f elf
one. ELF (executable and linkable format) is the linux format for executables; Windows requires Portable Executable (PE) images. The nasm option is -f win32
, or for dos nasm -f coff
.
我假设你没有使用那个-f elf
。ELF(executable and linkable format)是linux的可执行文件格式;Windows 需要可移植可执行 (PE) 映像。nasm 选项是-f win32
, 或 用于 dos nasm -f coff
。
Edit 2just to check, I assembled the code and disassembled it again. I also used mingw. Anyway, I got:
编辑 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
The rest of the header appears to be a valid PE format executable with no Entry point specification. I believe therefore that the code is simply "falling through" to the first piece of assembly code to start. I wouldn't advise this behaviour, especially when linking multiple objects as I've no idea what would happen. Do use -entry
.
头的其余部分似乎是没有入口点规范的有效 PE 格式可执行文件。因此,我相信代码只是“落入”到要开始的第一段汇编代码。我不建议这种行为,尤其是在链接多个对象时,因为我不知道会发生什么。使用-entry
.
Disassembling the elf object file I get this:
反汇编 elf 目标文件我得到了这个:
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
In other words, there aren't any specific ELF-format headers in it. I believe you're getting lucky on this one; start importing or trying to link with other code modules and things will start to get more tricky.
换句话说,其中没有任何特定的 ELF 格式标头。我相信你在这一点上很幸运;开始导入或尝试与其他代码模块链接,事情将开始变得更加棘手。
For Windows / mingw, you want:
对于 Windows / mingw,您需要:
nasm -f win32 file.asm
for each file you want to assemble. Substitute win32
for win64
when needed. ld
will do fine for linking.
对于您要组装的每个文件。替换win32
为win64
在需要的时候。ld
链接会很好。
Just a thought - I never explained the @16
part. The functions are 16-byte aligned on Windows, whereas, as you can see, the data is only four-byte aligned. See this explanationfor the why.
只是一个想法 - 我从来没有解释过这个@16
部分。这些函数在 Windows 上是 16 字节对齐的,而正如您所见,数据仅是 4 字节对齐的。请参阅此解释以了解原因。