【问题标题】:Outputting Hello World in MASM using WIN32 Functions使用 WIN32 函数在 MASM 中输出 Hello World
【发布时间】:2011-06-01 21:12:48
【问题描述】:

内容

  1. 简介
  2. 代码
  3. 组装和运行
  4. 杂项
  5. 问题

1.简介

这本身不是一个问题(尽管底部有一个),而是一个供 StackOverflow 上的人们试验的 HelloWorld 应用程序。

当我第一次尝试在 MASM 中编程时,我试图找到一个使用 WIN32 API 调用(因此不链接到 C 库)但找不到一个(在 MASM 语法中)的工作 HelloWorld 应用程序。所以现在我有了一些经验,我写了一篇给其他想学习汇编的人来摆弄。

2。代码

.386 ; 386 Processor Instruction Set

.model flat,stdcall ; Flat memory model and stdcall method

option casemap:none ; Case Sensitive

;Libaries and Include files used in this project

; Windows.inc defines alias (such as NULL and STD_OUTPUT_HANDLE in this code
include \masm32\include\windows.inc 

; Functions that we use (GetStdHandle, WriteConsole, and ExitProcess)
; Listing of all available functions in kernel32.lib
include \masm32\include\kernel32.inc 
; Actuall byte code available of the functions
includelib \masm32\lib\kernel32.lib  

.data
; Labels that with the allocated data (in this case Hello World!...) that are aliases to memory.
output db "Hello World!", 0ah, 0h; This String Hello World! and then a the newline character \n (0ah) and then the null character 0h

.code 
start: 

; --------------------------------------------------------------------------------------------------------------------------------------
; Retrieves that handle to the output console
;
; ====Arguments===
;
; STD_OUTPUT_HANDLE - alias for -11 and indicates that we want the handle to 
;                     write to console output
;
invoke GetStdHandle, STD_OUTPUT_HANDLE
; --------------------------------------------------------------------------------------------------------------------------------------

; --------------------------------------------------------------------------------------------------------------------------------------
; Writes the text in output (.data section) to the console
;
; ====Arguments===
;
; eax - the handle to the console buffer
;
; addr output - pass by reference the text of output (Hello World!)
;
; sizeof output - the size of the string so that the WriteConsole knows when to 
;                 stop (doesn't support NULL terminated strings I guess);
;
; ebx - secondary "return" value that contains the number of bytes written (eax
;       is used for an error code)
;
; NULL - this is reserved and MSDN says just to pass NULL
;
; MSDN Link: http://msdn.microsoft.com/en-us/library/ms687401(v=VS.85).aspx
;
invoke WriteConsole, eax, addr output, sizeof output, ebx, NULL
; --------------------------------------------------------------------------------------------------------------------------------------

; --------------------------------------------------------------------------------------------------------------------------------------
; Exits the program with return code 0 (default one that usually is used to 
; indicate that the program did not error
;
; ====Arguments===
;
; 0 - the exit code
;
; MSDN Link: http://msdn.microsoft.com/en-us/library/ms682658(VS.85).aspx
;
invoke ExitProcess, 0
; --------------------------------------------------------------------------------------------------------------------------------------

end start 

3.组装和运行

我假设您在 C:\MASM32 目录中安装了 MASM32。

  • 如果您没有安装 MASM 请去 http://masm32.com/install.htm 并按照说明进行操作。

  • 如果 MASM32 安装在不同的 目录请更改 相应的指示。

    1. 通过单击桌面快捷方式打开 MASM32 编辑器 (QEditor),如果没有快捷方式,请转到 C:\MASM32\ 并双击 qeditor.exe

    2. 复制代码部分的代码(只有灰色背景的文本)并粘贴到MASM32编辑器(QEditor)中并保存。

    3. 保存代码后,单击项目菜单并选择控制台组装和链接(组装和链接(参见杂项))

      李>
    4. 转到“开始”并单击“运行”,然后键入 cmd 并按 ENTER,应出现一个带有灰色文本的黑框

    5. 使用资源管理器导航到您在步骤 3 中保存代码的位置。现在应该有一个与源文件(步骤 3)同名的文件,但它是一个 exe。将exe文件从资源管理器窗口拖放到cmd框(第4步黑框)

    6. 选择黑框并按 ENTER,文本“Hello World!”应该会出现。

4.杂项

为什么我必须点击控制台组装并运行,而不仅仅是项目菜单中的组装和运行?

您必须单击 Console Assemble and Run 的原因是因为有两种类型的应用程序,一种是 GUI,另一种是文本基本控制台 (DOS) 应用程序。 Hello Will 应用程序是基于文本的应用程序,因此在组装时必须具有基于控制台的应用程序而不是 GUI 的设置。

更详细的解释见this link备注下的第三段。

5.问题

好的,现在的问题是,这里是否有人看到此代码的任何问题、错误或一般问题或有任何建议

【问题讨论】:

    标签: winapi assembly masm masm32


    【解决方案1】:

    程序很好。它确实是 Win32 的“Hello World”版本。但是,请记住它是一个控制台程序。在 Win32 中,您将主要处理 Windows、对话框,而很少使用控制台(以防万一,您想专门处理控制台,那是另一回事)。

    如果你想学习 Win32 Assembly,我强烈建议你看看 Iczelion 教程。

    这是他的教程开始的“Hello World”:

    http://win32assembly.online.fr/tut2.html

    【讨论】:

    • 我在看它们,它们确实是一套很好的教程,但几乎所有的编程教程都是从控制台和命令行应用程序开始的。
    • 我同意,但是在win32编程的情况下它是一个例外,因为你在这里学习的不是语言而是win32平台。
    【解决方案2】:

    此示例代码更简单易懂

    .386
    .model flat, stdcall
    option casemap: none
    
    include windows.inc
    include user32.inc
    include kernel32.inc
    includelib user32.lib
    includelib kernel32.lib
    
    .data
        szCaption   db  'Hello', 0
        szText      db  'Hello, World!', 0
    
    .code
        start:
                invoke MessageBox, NULL, offset szText, offset szCaption, MB_OK
                invoke ExitProcess, NULL        
        end start
    

    【讨论】:

    • 嗯,这是 a) 相当旧 b) 没有按照代码的预期执行! c) 对初学者没有任何解释!
    • 这不是旧的......它编译......并使用 Win32 API 打印一个 Hello World 消息框......调用是一种更快的方式,而不是推送参数
    • 嗯,这个问题已经有一年多了,它已经过时了......这也是为了展示如何在没有调用的情况下做到这一点,它为你做了很多事情。
    【解决方案3】:

    StdOut 是一个控制台函数

    您可以使用 MessageBox 功能...

    .model small,pascal,nearstack
    .386
    ?WINPROLOGUE=1
    include win.inc
    includelib libw.lib
    extern __astart:proc
    
    .data
    text sbyte "Hello f*** World!",0
    title sbyte "Win",0
    
    .code
    WinMain    PROC, hInstance:HANDLE, hPrevInstance:HANDLE, lpszCmdLine:LPSTR, nCmdShow,WORD
      LOCAL msg:MSG
    
     invoke MessageBox, NULL, addr text, addr title, 0
     invoke PostQuitMessage,0
    
     .while TRUE
         invoke GetMessage,addr msg,NULL,0,0
         .break .if (ax == 0)
         invoke TranslateMessage,addr msg
         invoke DispatchMessage,addr msg
     .endw
    WinMain    ENDP
    END        __astart
    

    【讨论】:

    • 这是经典的 hello world,就像在 c 中使用 printf 一样。
    猜你喜欢
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多