错误a2070无效指令操作数

时间:2013-10-08 03:43:38

标签: assembly x86 masm

我是Win32汇编中的新手:

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

  

错误a2070无效指令操作数(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

- >这没关系。

但我不明白为什么???

任何人都可以帮助我。

1 个答案:

答案 0 :(得分:2)

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

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

这只是x86指令集的限制; x86指令集没有内存到内存移动。您必须像使用pushpop一样将其分为两个说明。