如何使用汇编语言编写一个“Hello World”应用程序?

11
可能重复:如何在Windows下使用汇编语言编写“Hello World!”? 我经常听说过使用诸神之语——汇编语言编写的应用程序。但我从未尝试过,也不知道该如何入手。
如果我想尝试一下,我该怎么做呢?我对所需的一切都一无所知,尽管大概需要某种编译器和记事本。
出于纯粹好奇的目的,我需要什么才能编写一个“Hello World!”应用程序呢?
编辑添加,我正在运行Windows 7 64位版。
编辑添加,我想知道是否有Visual Studio的汇编语言插件?

2
重复的https://dev59.com/e3NA5IYBdhLWcg3wSrua - Richard Ev
4个回答

7

如果只是为了这个目的,编写64位代码并没有任何意义,还不如坚持使用32位代码。

如果您想要输出到MessageBox,可以像这样:

.386
.MODEL flat, stdcall

MessageBoxA PROTO near32 stdcall, window:dword, text:near32,
        windowtitle:near32, style:dword

.stack 8192

.data
message db "Hello World!", 0
windowtitle   db "Win32 Hello World.", 0

.code
main proc
        invoke MessageBoxA, 0, near32 ptr message, near32 ptr windowtitle, 0
        ret
main endp
        end main

如果你想要将输出显示在控制台上,这需要(奇怪地)更加复杂:

.386
.MODEL flat, stdcall

getstdout = -11

WriteFile PROTO NEAR32 stdcall,     \
        handle:dword,                   \
    buffer:ptr byte,        \
        bytes:dword,                    \
        written: ptr dword,             \
        overlapped: ptr byte

GetStdHandle PROTO NEAR32, device:dword

ExitProcess PROTO NEAR32, exitcode:dword

.stack 8192

.data
message db "Hello World!"
msg_size equ $ - offset message

.data?
written  dd ?

.code
main proc   
    invoke GetStdHandle, getstdout
    invoke WriteFile,                   \
           eax,                         \
           offset message,              \
           msg_size,                    \
           offset written,              \
           0

    invoke ExitProcess, 0
main endp
        end main

理论上,转换为64位代码并没有太大的区别——例如,您可以在两者中使用相同的函数。但实际上,这有点麻烦,因为64位代码的调用约定有些复杂,而且您不能在64位代码中使用MASM的invoke。工作代码不会变得非常复杂,但让代码正常运行可能需要更多的工作。总体思路是对于64位代码,您需要在堆栈上为所有参数分配空间,但是前N个小到足以放入寄存器的参数将进入寄存器。


为什么控制台输出如此复杂?当我还在做汇编语言时,写字符串只需要一个微不足道的中断调用...我记得是 int 10h,但我不能确定。它只需要四条指令,不需要外部库。 - rmeador
@rmeador:长度主要是因为它们将控制台视为普通文件,并且WriteFile在这种情况下需要我们不太关心的额外参数。理论上,您可以使用WriteConsoleOutput或类似的东西,但这也是非常复杂的。 - Jerry Coffin
这真的是所需的全部吗?我以为你需要设置大量的代码部分之类的东西。一个 ASM Windows 应用怎么可能比所有需要的 C++ 代码都要短得多呢?它只比一个C++控制台“Hello World”长一点点! - Mr. Boy
@John:第一个的C++等效代码应该是:int main() { return MessasgeBox(NULL, "Hello World!", "Win32 Hello World", MB_OK); } - Jerry Coffin
哦,好的。我从来不知道你可以如此简单地访问Win32 API,而无需先加载大量的初始化代码。 - Mr. Boy

2

1

fasm中:

include 'win32axp.inc'

.code
  start:
        invoke  AllocConsole
        invoke  WriteConsole,<invoke GetStdHandle,STD_OUTPUT_HANDLE>,tex,tex.size,dummy,0
        invoke  Sleep,-1
.end start

.data
tex     TCHAR   'Hello World!'
 .size  =       ($-tex)
dummy   rd      1   

1

我建议您寻找支持Intel风格汇编语法的工具,而不是AT&T可怕的语法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接