assembly - 错误 a2070 指令操作数无效

标签 assembly x86 masm

我是 Win32 程序集的新手:

我学习了这个程序的代码,它的窗口很简单。但我收到错误:

error a2070 invalid instruction operands (MASM)

我在google上搜索过这个错误,但还是不明白。

.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

WinMain PROTO :HINSTANCE, :HINSTANCE, :LPSTR, :DWORD

.data
    AppName     db "First Windows", 0
    ClassName   db "Window Class", 0

.data?
    hInstance   dd ?
    CommandLine dd ?

.code
start:
    invoke  GetModuleHandle, NULL
    MOV     hInstance, EAX
    invoke  GetCommandLine
    MOV     CommandLine, EAX
    invoke  WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
    invoke  ExitProcess, EAX

    WinMain PROC ahInstance:HINSTANCE, \
            ahPrevInstance:HINSTANCE, \
            aCommandLine:LPSTR, \
            aCommandShow:DWORD
        LOCAL   wc:WNDCLASSEX
        LOCAL   hwnd:HANDLE
        LOCAL   msg:MSG

        MOV     wc.cbSize, SIZEOF WNDCLASSEX
        MOV     wc.style, CS_HREDRAW or CS_VREDRAW
        MOV     wc.lpfnWndProc, offset WndProc
        MOV     wc.cbClsExtra, NULL
        MOV     wc.cbWndExtra, NULL
        MOV     wc.hInstance, hInstance ;;;;;;;;;;;;;;;; Error here

        invoke  LoadIcon, NULL, IDI_APPLICATION
        MOV     wc.hIcon, EAX
        MOV     wc.hIconSm, EAX
        invoke  LoadCursor, NULL, IDC_ARROW
        MOV     wc.hCursor, EAX
        MOV     wc.hbrBackground, COLOR_WINDOW+1
        MOV     wc.lpszMenuName, NULL
        MOV     wc.lpszClassName, offset ClassName

        invoke  RegisterClassEx, addr wc

        invoke  CreateWindowEx, NULL, addr ClassName, addr AppName, \
                WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, \
                CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, ahInstance, NULL
        MOV     hwnd, EAX

        invoke  ShowWindow, hwnd, SW_SHOWNORMAL
        invoke  UpdateWindow, hwnd

        .WHILE TRUE
            invoke  GetMessage, addr msg, NULL, 0, 0
            .BREAK .IF (!EAX)
            invoke  TranslateMessage, addr msg
            invoke  DispatchMessage, addr msg
        .ENDW

        MOV EAX, msg.wParam
        RET
    WinMain endp

    WndProc PROC ahWnd:HWND, aMsg:DWORD, awParam:WPARAM, alParam:LPARAM
        .IF aMsg == WM_DESTROY
            invoke  PostQuitMessage, NULL
        .ELSE
            invoke  DefWindowProc, ahWnd, aMsg, awParam, alParam
            ret
        .ENDIF
        XOR EAX, EAX
        ret
    WndProc endp
end start

那一行:

MOV     wc.hInstance, hInstance

出现错误,我替换为:

PUSH hInstance
POP  wc.hInstance

--> 这样就可以了。

但我不明白为什么???

任何人都可以帮助我。

最佳答案

wc.hInstance 引用 wc 的一部分,它位于堆栈上,因此位于内存中。 hInstance 也在堆栈上,因此位于内存中。如果您尝试任何内存到内存的移动,您会发现它不起作用:

mov [esp], [ebp]
error: invalid operand.

这只是 x86 指令集的限制; x86 指令集没有内存到内存的移动。您必须将其分成两条指令,就像使用 pushpop 那样。

关于assembly - 错误 a2070 指令操作数无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19238698/

相关文章:

c++ - 在 VS 代码中调试 NASM

assembly - 在带有 GCC 的 x86 PC 上组装 ARM asm 时出现错误或 `as`

c - 今天和 20 年前的内存对齐

c - gcc在调用前从esp中减去

assembly - 是否需要为 X64 快速调用叶函数保留 RCX?

assembly - 将寄存器设置为 1 的 MIPS 指令

我可以将 Intel 语法的 x86 程序集与 GCC 一起使用吗?

assembly - 在 NASM 中使用 OR r/m32、imm32

class - 程序集中的结构或类

memory - 汇编 - 尝试反转字符串,但它在最终字符串上添加了一个额外的字符