Hello world在windows程序集中使用nasm

Hello world在windows程序集中使用nasm,windows,assembly,mingw,nasm,Windows,Assembly,Mingw,Nasm,我正在使用编译以下程序集。但是,该代码在Windows下的控制台中崩溃 C:\>nasm-f win32 test.asm-o test.o C:\>ld test.o-o test.exe 据此,。main功能在Windows下不可用,必须用WinMain替换 因此,如果您的入口点是\u start或main,则应将其更改为_WinMain@16并将过程结束时的ret更改为ret 16: 我的工作示例: section .text global _WinMain@16

我正在使用编译以下程序集。但是,该代码在Windows下的控制台中崩溃

C:\>nasm-f win32 test.asm-o test.o

C:\>ld test.o-o test.exe

据此,。
main
功能在Windows下不可用,必须用
WinMain
替换

因此,如果您的入口点是
\u start
main
,则应将其更改为
_WinMain@16
并将过程结束时的
ret
更改为
ret 16

我的工作示例:

section .text       
 global _WinMain@16       

_WinMain@16:       
 mov eax, 0       
 ret 16 

最大的问题是,您试图在windows上使用Linux中断! int 80在windows上不起作用

我们使用的是Assembly,因此您的入口点可以是您想要的任何标签。ld查找的标准入口点是_start,如果您想使用另一个标签,则需要使用-e选项告诉ld 因此,如果您希望开始标签是主标签,那么您需要

global main
ld -e main test.o -o test.exe
如果您打算在Windows上使用NASM,我建议您使用GoLink作为链接器。 以下是一个简单的windows控制台应用程序:

STD_OUTPUT_HANDLE   equ -11
NULL                equ 0

global GobleyGook
extern ExitProcess, GetStdHandle, WriteConsoleA

section .data
msg                 db "Hello World!", 13, 10, 0
msg.len             equ $ - msg

section .bss
dummy               resd 1

section .text
GobleyGook:
    push    STD_OUTPUT_HANDLE
    call    GetStdHandle

    push    NULL
    push    dummy
    push    msg.len
    push    msg
    push    eax
    call    WriteConsoleA 

    push    NULL
    call    ExitProcess
生成文件:

hello: hello.obj
    GoLink.exe  /console /entry GobleyGook hello.obj kernel32.dll  

hello.obj: hello.asm
    nasm -f win32 hello.asm -o hello.obj

尽管如此,同样的程序可能会在Linux上的WINE中运行,非常有魅力。:)


WINE不会阻止从Windows PE二进制文件内部使用Linux系统调用;机器指令本机运行,WINE仅提供DLL函数。

请编辑标题,以便对未来的访问者有用。否则它可能会因为太本地化而关闭。@RaymondChen to what?@JayBlanchard这是一个答案,因为它指向操作系统,程序将在那里正常工作,而问题中没有提到崩溃。哦,你是说在Linux机器上,系统调用本机运行,WINE与它们无关。一开始我以为你的意思是WINE是双向的,它可以在Windows机器上模拟Linux
int0x80
ABI@PeterCordes WINE仅在Unix计算机上运行,并模拟Windows API。但只要程序不是在VM中运行,而是在Linux操作系统的内存中运行,它们就可以使用int 0x80系统调用。当然,这样的程序会在真正的Windows上崩溃。但是这个程序可以检测操作系统,并且只有在Linux上运行时才能使用这些调用。是的,我知道所有这些。我想说你的回答误导了我一分钟。请注意,WINE在一些非Linux操作系统(*BSD,包括OS X)上运行,在这些操作系统中,本机Linux系统调用无法工作。@Gunner谢谢。不过有一个问题——你为什么推荐GoLink而不推荐其他链接器?@Boris个人偏好我猜。发现它比Windows上的其他链接器更易于使用。消息字符串末尾的零字节不应存在。WriteConsoleA不需要它,它使用提供的字符串长度,事实上最终被写入控制台,在我尝试时显示为一个空格。删除零字节修复了该问题。Windows是否具有简单执行系统调用的等效功能,而不是调用ExitProcess和调用WriteConsoleA?64位Windows是否具有等效功能?如果我尝试执行win64的
-f
操作,我会在
推送eax
行中得到
错误:64位模式下不支持指令。
hello: hello.obj
    GoLink.exe  /console /entry GobleyGook hello.obj kernel32.dll  

hello.obj: hello.asm
    nasm -f win32 hello.asm -o hello.obj