Hello world 在 Windows 程序集中使用 nasm

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12574924/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 09:54:52  来源:igfitidea点击:

Hello world using nasm in windows assembly

windowsassemblymingwnasm

提问by fulvio

I'm using nasmto compile the following assembly. However the code crashes in the console under Windows.

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

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

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

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

According to this post. The mainfunction is not available under Windows and must be replaced by WinMain.

根据这个帖子。该main功能在 Windows 下不可用,必须替换为WinMain.

So if your entry point is _startor main, it should be changed to _WinMain@16and change the retat 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 

回答by Gunner

The biggest problem is that you are trying to use Linux interupts on windows! int 80 will NOT work on windows.

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

We are using Assembly, so your entry point can be ANY label you want. 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

我们使用的是Assembly,所以你的入口点可以是你想要的任何标签。ld 寻找的标准入口点是 _start,如果你想使用另一个标签,你需要用 -e 选项告诉 ld 所以如果你想让你的开始标签是 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. Here is a simple windows console app:

如果你打算在 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

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

回答by johnfound

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; the machine instructions run natively and WINE only provides DLL functions.

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