你好世界在Windows程序集中使用nasm

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

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

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

section .data msg db 'Hello world!', 0AH len equ $-msg section .text global _WinMain@16 _WinMain@16: mov edx, len mov ecx, msg mov ebx, 1 mov eax, 4 int 80h mov ebx, 0 mov eax, 1 int 80h 

根据这个post 。 mainfunction在Windows下不可用,必须由WinMainreplace。

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

我的工作例子:

 section .text global _WinMain@16 _WinMain@16: mov eax, 0 ret 16 

最大的问题是你正试图在Windows上使用Linux interupts! 诠释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函数。