在windows程序集中使用nasm的Hello world

时间:2012-09-25 01:03:16

标签: windows assembly mingw 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

根据这个postmain功能在Windows下不可用,必须由WinMain替换。

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

我的工作范例:

section .text       
 global _WinMain@16       

_WinMain@16:       
 mov eax, 0       
 ret 16 

2 个答案:

答案 0 :(得分:29)

最大的问题是你正试图在Windows上使用Linux interupts! int 80不适用于Windows。

我们正在使用汇编,因此您的入口点可以是您想要的任何标签。 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

答案 1 :(得分:7)

虽然,同样的程序可能会在Linux上的WINE中运行,就像魅力一样。 :)

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