简体   繁体   English

在Windows程序集中使用nasm的Hello World

[英]Hello world using nasm in windows assembly

I'm using nasm to compile the following assembly. 我正在使用nasm编译以下程序集。 However the code crashes in the console under Windows. 但是,代码在Windows下的控制台中崩溃。

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

C:\\>ld test.o -o test.exe 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

According to this post . 根据这个帖子 The main function is not available under Windows and must be replaced by WinMain . main功能在Windows下不可用,必须替换为WinMain

So if your entry point is _start or main , it should be changed to _WinMain@16 and change the ret at the end of the procedure to ret 16 : 因此,如果您的入口点是_startmain ,则应将其更改为_WinMain@16并在过程结束时将ret更改为ret 16

My working example: 我的工作示例:

section .text       
 global _WinMain@16       

_WinMain@16:       
 mov eax, 0       
 ret 16 

The biggest problem is that you are trying to use Linux interupts on windows! 最大的问题是您试图在Windows上使用Linux中断! int 80 will NOT work on windows. int 80在Windows上不起作用。

We are using Assembly, so your entry point can be ANY label you want. 我们正在使用Assembly,因此您的入口点可以是您想要的任何标签。 The standard entry point that ld looks for is _start, if you want to use another label, you need to tell ld with the -e option So if you want your start label to be main, then you need ld查找的标准入口点是_start,如果要使用其他标签,则需要使用-e选项告诉ld。因此,如果希望start标签为main,则需要

global main
ld -e main test.o -o test.exe

If you are going to use NASM on Windows, I will recommend using GoLink as your linker. 如果要在Windows上使用NASM,我建议使用GoLink作为链接器。 Here is a simple windows console app: 这是一个简单的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

makefile: 生成文件:

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

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

Although, this same program probably will run in WINE on Linux like a charm. 虽然,同样的程序可能会像魅力一样在Linux上的WINE中运行。 :) :)

WINE doesn't prevent using Linux system calls from inside Windows PE binaries; WINE不会阻止从Windows PE二进制文件内部使用Linux系统调用; the machine instructions run natively and WINE only provides DLL functions. 机器指令本机运行,WINE仅提供DLL函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM