正在看罗云彬的《WIN32汇编开发》,目前看到了第五章,使用菜单资源。我尝试自己编写asm文件,用NMAKE操作后出现报错提示
Microsoft (R) Program Maintenance Utility Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.
ml /c/coff Menu.asm
Microsoft (R) Macro Assembler Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
MASM : warning A4018:invalid command-line option : /c/coff
Assembling: Menu.asm
Menu.asm(173) : fatal error A1010:unmatched block nesting : .if-.repeat-.while
NMAKE : fatal error U1077: 'E:\Masm32\Bin\ml.EXE' : return code '0x1'
Stop.
我认为主要错误是
“Menu.asm(173) : fatal error A1010:unmatched block nesting : .if-.repeat-.while”
.if或是.while嵌套错误,可是找了许久都没有发现类似Bug。以下是源代码,其中红色字我认为可能出错的地方。希望各位大侠能够指点迷津。
;//////////////////////////////////////////////
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
ico_main equ 1000h
idm_main equ 2000h
ida_main equ 2000h
idm_open equ 4101h
idm_option equ 4102h
idm_exit equ 4103h
idm_help equ 4104h
idm_func equ 4105h
idm_toolbar equ 4209h
idm_statusbar equ 4212h
idm_about equ 4302h
;/////////////////////////////////////////////////
.data?
hInstance dd ?
hWinMain dd ?
hMenu dd ?
hSubMenu dd ?
.const
szClassName db 'Menu_ClassName',0
szCaptionMain db 'Menu_CaptionMain',0
szMenuHelp db 'Help_MenuHelp',0
szMenuAbout db 'About',0
szCaption db 'Menu Option',0
szFormat db 'Format',0
;/////////////////////////////////////////////////
.code
displaymenu proc _dwCommandID
local @szBuffer[256]:byte
pushad
invoke wsprintf,addr @szBuffer,addr szFormat,_dwCommandID
invoke MessageBox,hWinMain,addr @szBuffer,offset szCaption,MB_OK
popad
ret
displaymenu endp
;/////////////////////////////////////////////////
quit proc
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
ret
quit endp
;/////////////////////////////////////////////////
_ProcWinMain proc uses edx edi esi hWnd,uMsg,wParam,lParam
local @stPos:POINT
local @hSysMenu
mov eax,uMsg
;////////////////////////////////////创建窗口////
.if eax==WM_CREATE
invoke GetSubMenu,hMenu,1
mov hSubMenu,eax
invoke GetSystemMenu,hWnd,FALSE
mov @hSysMenu,eax
invoke AppendMenu,@hSysMenu,MF_SEPARATOR,0,NULL
invoke AppendMenu,@hSysMenu,0,idm_help,offset szMenuHelp
invoke AppendMenu,@hSysMenu,0,idm_about,offset szMenuAbout
;///////////////////////////////////////菜单命令///////
.elseif eax==WM_COMMAND
invoke displaymenu,wParam
mov eax,wParam
movzx eax,ax
.if eax==idm_exit
call quit
.elseif eax>=idm_toolbar&&eax<=idm_statusbar
mov ebx,eax
invoke GetMenuState,hMenu,ebx,MF_BYCOMMAND
.if eax==MF_CHECKED
mov eax,MF_UNCHECKED
.else
mov eax,MF_CHECKDED
.endif
invoke CheckMenuItem,hMenu,ebx,eax
;////////////////////////////////////处理系统菜单////
.elseif eax==WM_SYSCOMMAND
mov eax,wParam
movzx eax,ax
.if eax==idm_help||eax==idm_about
invoke displaymenu,wParam
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret ;//////??????
.endif
;////////////////////////////////////////////////////////
.elseif eax==WM_RBUTTONDOWN
invoke GetCursorPos,addr @stPos
invoke TrackPopupMenu,hSubMenu,TPM_LEFTALIGN,@stPos.x,@stPos.y,NULL,hWnd,NULL
.elseif eax==WM_CLOSE
call quit
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
_ProcWinMain endp
;/////////////////////////////////////////////////
_WinMain proc
local @stWndClass:WNDCLASSEX
local @hAccelerator
local @stMsg:MSG
;//////////////////////////////////////得到句柄///
invoke GetModuleHandle,NULL
mov hInstance,eax
;//////////////////////////////////////对stWndClass置零///
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
;/////////////////////////////////////////////////
;//////// invoke LoadCursor,0,idc_main
;///////////////////////////////////////获取菜单句柄//////
invoke LoadMenu,hInstance,idm_main
mov hMenu,eax
;//////////////////////////////////////
;//////// invoke LoadAccelerators,hInstance,ida_main
;/////// invoke @hAccelerator,eax
;//////////////////////////////////////
invoke LoadIcon,hInstance,ico_main
mov @stWndClass.hIcon,eax
mov @stWndClass.hIconSm,eax
;///////////////////////////////////////////////////
push hInstance
pop @stWndClass.hInstance
;///////////////////////////////指定WNDCLASSEX长度///
mov @stWndClass.cbSize,sizeof WNDCLASSEX
;///////////////////////////////类风格////////
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
;///////////////////////////////窗口过程地址////
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
;///////////////////////////////背景色////////
mov @stWndClass.hbrBackground,COLOR_WINDOW+1
;///////////////////////////////类名字符串地址??////
mov @stWndClass.lpszClassName,offset szClassName
invoke RegisterClassEx,addr @stWndClass
;///////////////////////////////////////////////////////
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,WS_OVERLAPPEDWINDOW,100,100,400,300,NULL,hMenu,hInstance,NULL
mov hWinMain,eax
;///////////////////////////////////////////////////////
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
;////////////////////////////////////////循环/////
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break
.if eax==0
;/////////////
invoke TranslateAccelerator,hWinMain,@hAccelerator,addr @stMsg
.if eax==0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endif
.endw
ret
_WinMain endp
;/////////////////////////////////////////////////
start:
call _WinMain
invoke ExitProcess,NULL
end start
[课程]Linux pwn 探索篇!