Win32汇编学习笔记(二)

模仿win32Hello,World程序:

        . 386
        .model flat,stdcall
        option 
casemap: none
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
 Include 文件定义
;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include        windows. inc
include        gdi32.
inc
includelib    gdi32.lib
include        user32.
inc
includelib    user32.lib
include        kernel32.
inc
includelib    kernel32.lib

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
 数据段
;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .data?
hInstance    dd        ?        
; 应用程序句柄
hWinMain    dd        ?         ; 窗口句柄

        .const
szClassName    db    
' MyClass ' , 0          ; 窗口类名称
szCaptionMain    db     ' My first Window ! ' , 0          ; 窗口标题
szText        db     '  Hello,Win32 Assembly!! ' , 0          ; 要显示的信息
szButton     db     ' button ' , 0
szButtonText    db    
' 点我吧!! ' , 0
szMsgTitle db 
' 信息 ' , 0
szErrorMsg db 
' 出错啦!! ' , 0

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
 代码段
;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .code

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
 出错处理过程
;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ErrorProc proc    
        invoke MessageBox,NULL,offset szErrorMsg,offset szMsgTitle,MB_OK
        
ret
_ErrorProc endp
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
 窗口过程
;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain    proc    uses ebx edi esi hWnd,uMsg,wParam,lParam             ; 让汇编器保持子程序中使用到的寄存器的正确性 
        local     @stPs: PAINTSTRUCT            
        local    
@stRect: RECT
        local    @hDc            

        
mov     eax,uMsg
; ********************************************************************
        .if eax == WM_CREATE
            invoke CreateWindowEx,NULL,offset szButton,offset szButtonText,\
                            WS_CHILD 
or  WS_VISIBLE, 100 , 100 , 65 , 50 ,hWnd, 1 ,hInstance,NULL
; ********************************************************************
        .elseif    eax ==    WM_PAINT
            invoke    BeginPaint,hWnd,addr @stPs
            
mov     @hDc,eax

            invoke    GetClientRect,hWnd,addr @stRect
            invoke    DrawText,@hDc,addr szText,-
1 ,\      ; 长度设置为-1,表示输出的字符串以'\0'结尾,且由函数自动计算出其长度
                addr @stRect,\
                DT_SINGLELINE 
or  DT_CENTER  or  DT_VCENTER

            invoke    EndPaint,hWnd,addr @stPs
; ********************************************************************
        .elseif eax == WM_COMMAND
            invoke    MessageBox,NULL,offset szText,offset szMsgTitle,MB_OK
; ********************************************************************
        .elseif    eax ==    WM_CLOSE
            invoke    DestroyWindow,hWinMain
            invoke    PostQuitMessage,NULL
; ********************************************************************
        .else
            invoke    DefWindowProc,hWnd,uMsg,wParam,lParam
            
ret
        .endif
; ********************************************************************
         xor     eax,eax             ; eax寄存器清零
         ret

_ProcWinMain    endp
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
WinMain函数
;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

_WinMain    proc
        local    
@stWndClass: WNDCLASSEX
        local    
@stMsg: MSG
        
        invoke    GetModuleHandle,NULL   
; 获取应用程序句柄,这在VC里是通过操作系统传递进来的,但是汇编中需要自己去获取
         mov     hInstance,eax             ; 获取到的应用程序句柄在eax中
        invoke    RtlZeroMemory,addr @stWndClass,sizeof @stWndClass   ; 清零
;
********************************************************************
;
 注册窗口类
;
********************************************************************
        invoke    LoadCursor, 0 ,IDC_ARROW     ; 加载光标
         mov     @stWndClass.hCursor,eax            
        
push     hInstance
        
pop     @stWndClass.hInstance
        
mov     @stWndClass.cbSize,sizeof WNDCLASSEX
        
mov     @stWndClass.style,CS_HREDRAW  or  CS_VREDRAW

        
mov     @stWndClass.lpfnWndProc,offset _ProcWinMain         ; 设置窗口处理函数
         ; invoke GetStockObject,WHITE_BRUSH
         ; mov @stWndClass.hbrBackground,eax
         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 , 600 , 400 ,\
            NULL,NULL,hInstance,NULL                    
; 创建窗口,发出一个WM_CREATE消息
         mov     hWinMain,eax                         ; 保存窗口句柄
        invoke    ShowWindow,hWinMain,SW_SHOWNORMAL                 ; 显示窗口
        invoke    UpdateWindow,hWinMain                                         ; 发出一个WM_PAINT消息
;
********************************************************************
;
 第一种消息循环,使用GetMessage,同步的
;
********************************************************************
         ; .while    TRUE
             ; invoke    GetMessage,addr @stMsg,NULL,0,0
             ; .break    .if eax    == 0                    ;stMsg为0,即收到WM_QUIT消息时退出
             ; invoke    TranslateMessage,addr @stMsg
             ; invoke    DispatchMessage,addr @stMsg
         ; .endw
;
********************************************************************
;
另一种消息循环,使用PeekMessage,异步的
;
********************************************************************
        .while TRUE
            invoke PeekMessage,addr @stMsg,NULL,
0 , 0 ,PM_REMOVE
            .if eax != 
0
                    .break  .if @stMsg.message == WM_QUIT
                    invoke    TranslateMessage,addr @stMsg
                    invoke    DispatchMessage,addr @stMsg 
            .else
                    
; 空闲时间,可以做其他处理工作
            .endif
        .endw
        
ret
_WinMain endp

; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
程序入口点
;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
        
call     _WinMain    
        invoke    ExitProcess,NULL
; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        end    start



运行结果:


2008030702.jpg

你可能感兴趣的:(Win32)