Hello world在windows程序集中使用nasm
我正在使用编译以下程序集。但是,该代码在Windows下的控制台中崩溃 C:\>nasm-f win32 test.asm-o test.o C:\>ld test.o-o test.exe 据此,。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
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