【问题标题】:Assembly programming - WinAsm vs Visual Studio 2017汇编编程 - WinAsm 与 Visual Studio 2017
【发布时间】:2019-03-18 16:12:18
【问题描述】:

我是来问你一些关于 VS2017 的问题。
过去我曾将 WinAsm 用于 MASM,但从未遇到过问题。

但是,当我尝试在 VS2017 中使用 MASM 做某事时,我总是会遇到问题和东西...
我已经检查了整个互联网关于“如何为 MASM 设置 VS”,但没有任何帮助,因为我总是遇到麻烦......

有没有什么方法可以使用 Visual Studio 2017 for MASM32/64bit 而不会让人头疼?

谁能给我设置 VS2017 进行汇编编程的终极指南?

非常感谢你,对不起我的英语不好。

【问题讨论】:

    标签: assembly visual-studio-2017 ide masm instructions


    【解决方案1】:

    如何使用独立的 x64/x86 程序集文件构建 x64/x86 项目

    1) 启动 Visual Studio (Community) 2017 并选择 FILE - New - Project

    2) 在下一个窗口中选择Empty Project

    3) 确保项目在解决方案资源管理器中突出显示,然后选择 PROJECT - Build Customizations...

    4) 在下一个窗口中勾选masm(.targets,.props) 并点击OK

    5) 从菜单中选择PROJECT - Add New Item

    6) 在下一个窗口中选择 C++File(.cpp) 和 - 重要提示! - 给它一个带有 .asm 扩展名的名称。点击Add

    7) 现在您可以用内容填充文件了。

    Source.asm:

    EXTERN GetStdHandle : PROC
    EXTERN WriteFile    : PROC
    EXTERN ExitProcess  : PROC
    
    .DATA?
        hFile           QWORD ?
        BytesWritten    DWORD ?
    
    .DATA
        hello   BYTE 'Hello world!', 13, 10
    
    .CODE
    main PROC
        ; https://blogs.msdn.microsoft.com/oldnewthing/20160623-00/?p=93735
        sub rsp, 40                 ; Shadow space (4 * 8) & 1 parameter (8 bytes)
        ; https://docs.microsoft.com/en-us/cpp/build/stack-allocation
        and spl, -16                ; Align to 16
    
        ; https://msdn.microsoft.com/library/windows/desktop/ms683231.aspx
        mov ecx, -11                ; DWORD         nStdHandle = STD_OUTPUT_HANDLE
        call GetStdHandle           ; Call WinApi
        mov hFile, rax              ; Save returned handle
    
        ; https://msdn.microsoft.com/library/windows/desktop/aa365747.aspx
        mov rcx, hFile              ; HANDLE        hFile (here: Stdout)
        lea rdx, hello              ; LPCVOID       lpBuffer
        lea r9, BytesWritten        ; LPDWORD       lpNumberOfBytesWritten
        mov r8d, LENGTHOF hello     ; DWORD         nNumberOfBytesToWrite
        mov qword ptr [rsp+32], 0   ; LPOVERLAPPED  lpOverlapped = NULL
        call WriteFile              ; Call WinAPI
    
    exit:
        ; https://msdn.microsoft.com/library/windows/desktop/ms682658.aspx
        xor ecx, ecx                ; Set RCX to null for return value
        call ExitProcess            ; Call WinAPI to exit
    main ENDP
    
    end
    

    这是一个 64 位控制台应用程序,从过程 main 开始。

    8) 将 Solution Platforms 更改为 x64

    9) 选择PROJECT - Properties

    10) 在“属性”窗口中,您必须完成两个链接器选项:

    • 入口点:主要
    • 子系统:控制台 (/SUBSYSTEM:CONSOLE)

    在左侧选择Configuration Properties - Linker - All Options,同时更改两个选项,然后单击OK

    11) 使用 CTRL-F5 构建并运行 .exe。应用程序将在新窗口中打开。


    现在用 32 位控制台应用程序覆盖 Source.asm

    .MODEL flat, stdcall
    
    ; https://docs.microsoft.com/en-us/cpp/assembler/masm/proto
    GetStdHandle PROTO STDCALL,     ; https://docs.microsoft.com/en-us/windows/console/getstdhandle
        nStdHandle: SDWORD
    WriteFile PROTO STDCALL,        ; https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-writefile
        hFile: DWORD,                       ; output handle
        lpBuffer: PTR BYTE,                 ; pointer to buffer
        nNumberOfBytesToWrite: DWORD,       ; size of buffer
        lpNumberOfBytesWritten: PTR DWORD,  ; num bytes written
        lpOverlapped: PTR DWORD             ; ptr to asynchronous info
    ExitProcess PROTO STDCALL,      ; https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-exitprocess
        dwExitCode: DWORD                   ; return code
    
    .DATA                   ; https://docs.microsoft.com/en-us/cpp/assembler/masm/dot-data
        Hallo db "Hello world!",13,10
    
    .DATA?                  ; https://docs.microsoft.com/en-us/cpp/assembler/masm/dot-data-q
        lpNrOfChars dd ?
    
    .CODE                   ; https://docs.microsoft.com/en-us/cpp/assembler/masm/dot-code
    main PROC               ; docs.microsoft.com/en-us/cpp/assembler/masm/proc
        invoke GetStdHandle, -11            ; -> StdOut-Handle into EAX
        invoke WriteFile, eax, OFFSET Hallo, LENGTHOF Hallo, OFFSET lpNrOfChars, 0
        invoke ExitProcess, 0
    main ENDP
    
    END main                ; https://docs.microsoft.com/en-us/cpp/assembler/masm/end-masm
    

    Solution Platforms更改为x86(上面的第8个)并用SubSystem: Console (/SUBSYSTEM:CONSOLE)完成项目属性(上面的第10个)。您不得设置入口点,因为 ml32 需要 END 指令 (END main) 之后的入口点。使用 CTRL-F5 构建并运行 .exe。

    【讨论】:

    • 相关:external assembly file in visual studio 用于将 asm 文件添加到 C++ 项目
    • @rkhb 在 x64 中使用 CTRL+F5 构建和运行 .exe 时,出现链接器错误:error LNK2001: unresolved external symbol mainCRTStartup
    • @Belloc:奇怪。我刚刚使用 VS Community 2017 版本 15.9.16 对其进行了测试。有用。您是否忘记指定入口点(我的指令的第 10 号)?
    • 我的是 VS2017 15.9.17。我重新检查了第 10 步,一切正常。消息仍然存在。在我的 OneDrive 中查看 printscreen
    • VS2017 说它无法打开文件 *.asm(A1000 错误)。在 VS2015 上它工作正常(x86 和 x64)。但是,你必须删除所有的cmets,否则会出现编译错误(至少在我的机器上)。而且它不识别.data?指令,因此,将所有相关变量放在 .data 部分下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-08
    • 2017-08-28
    • 1970-01-01
    相关资源
    最近更新 更多