在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 17:09:41  来源:igfitidea点击:

programming with NASM in Windows XP

windowsnasmwinmain

提问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- requires mainand linking with msvcrXX.dll. These applications run in console windows; if you aren't running an instance of cmd.exe, one will be opened.
  • /SUBSYSTEM:WINDOWS- WinMainis the starting point. See here. Usually in C, these #include <windows.h>and are linked directly to kernel32.dll. These a gui apps and are almost definitely linked with user32.dlland possibly advapi32.dllas well.
  • /SUBSYSTEM:NATIVE- there are two types of application here; drivers and applications. Native NT apps run during windows startup and require NtProcessSStartupas 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.exeis available here.

此处link.exe提供了受支持的 Windows 子系统的完整列表。

_startis the symbol windows will actually start your code running at. Normally, libcor the like actually handles _startand does some initial setup, so your program doesn't actually quite start at _main. If you wanted to link with libcyou 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 elfone. 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 win32for win64when needed. ldwill do fine for linking.

对于您要组装的每个文件。替换win32win64在需要的时候。ld链接会很好。

Just a thought - I never explained the @16part. 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 字节对齐的。请参阅此解释以了解原因。