【问题标题】:How can I write a "Hello World" app in assembly language? [duplicate]如何用汇编语言编写“Hello World”应用程序? [复制]
【发布时间】:2011-02-08 20:56:19
【问题描述】:

可能重复:
how to write hello world in assembler under windows?

我经常听说使用众神的语言——汇编语言编写的应用程序。不过我从来没有尝试过,我什至不知道该怎么做。

如果我想涉足,我会怎么做?我完全不知道需要什么,虽然大概是某种编译器和记事本。

纯粹出于好奇,我需要什么来写一个“Hello World!”申请?

编辑添加,我运行的是 Windows 7 64bit

编辑添加,不知Visual Studio有没有汇编语言插件?

【问题讨论】:

标签: assembly x86 x86-64


【解决方案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   

【讨论】:

    【解决方案2】:

    我建议你找到一个支持 Intel 风格 ASM 的工具,而不是 AT&T 可怕的语法。

    【讨论】:

      【解决方案3】:

      为此,编写 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 位代码的调用约定有些复杂,并且不能使用 MASM 的invoke 来处理 64 位代码。工作代码不会整体复杂得多,但让代码工作可能需要更多的工作。一般的想法是,对于 64 位代码,您在堆栈上为所有参数分配空间,但前 N 个小到足以容纳的参数进入寄存器。

      【讨论】:

      • 为什么写控制台这么复杂?回到我做汇编的时候,写一个字符串是一个微不足道的中断调用......我认为它是 int 10h,但我无法确定。就像 4 条指令,不需要外部库。
      • @rmeador:长度主要是因为他们将控制台视为普通文件,而 WriteFile 采用了我们在这种情况下不太关心的额外参数。从理论上讲,您可以使用WriteConsoleOutput 或该订单上的其他内容,但这也很重要。
      • 真的只需要这些吗?我以为你必须设置大量的代码段和东西。 ASM Windows 应用程序怎么能比所需的所有 C++ 代码短这么多?它只比 C++ 控制台“Hello Word”长一点!
      • @John:第一个的 C++ 等效项是:int main() { return MessasgeBox(NULL, "Hello World!", "Win32 Hello World", MB_OK); }
      • 哦,好的。我从来不知道你可以如此简单地访问 Win32 API,而无需先加载初始化代码。
      【解决方案4】:

      看看WinAsm

      【讨论】:

        猜你喜欢
        • 2023-03-16
        • 1970-01-01
        • 2010-11-04
        • 2013-01-24
        • 1970-01-01
        • 2023-02-07
        • 2013-10-29
        相关资源
        最近更新 更多