我的第一个Win32汇编程序

这是我的第一个Win32汇编程序,实现的效果就是画线,并能拖出橡皮线,刷新后不丢失数据。虽然功能很简单,若用VC++说不定一个小时就over,但是这个整整用了三天。现在我将程序贴出来恭大家批评指正。
我用的开发工具是:编辑器:EditPlus+asm语法文件,编译连接器Masm32v8,调试器:Ollydbg,make工具:VC++的nmake

 .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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 .data?
hInstance dd ?
hWinMain dd ?
m_isLine dd ?
m_X  dd ?
m_Y  dd ?
m_dragX  dd ?
m_dragY  dd ?
m_f  dd ?   ;the flag
m_data  dd 1024 dup (0) ;the points buffer
m_pdata  dd ?   ;the number of the points in the buffer

 .const
szClassName db 'MyClass',0
szCaptionMain db '画线',0

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; code
; WinProc
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 .code
_ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
  local @stPs:PAINTSTRUCT
  local @stRect:RECT
  local @hDc
  local @a1,@a2,@a3,@a4


 mov eax,uMsg
;********************************************************************
 .if eax == WM_LBUTTONDOWN
  invoke SetCapture,hWnd
  or m_isLine,1 ;the left button is pressed
  mov ebx,lParam ;store mouse position
  and ebx,0000FFFFH
  mov m_X,ebx
  mov ebx,lParam
  shr ebx,00000010H
  mov m_Y,ebx
  mov m_f,0  ;0 means first time mouse move when drawing a line
;**************************************************************************************
 .elseif eax == WM_MOUSEMOVE
  mov ebx,m_isLine ;the left button is pressed
  .if ebx == 1
   invoke GetDC,hWnd
   mov @hDc,eax
   invoke SetROP2,@hDc,R2_NOTXORPEN

   mov ebx,m_f

   ;the next block means NOT the first time mouse move when drawing a line
   .if ebx == 1
    invoke MoveToEx,@hDc,m_X,m_Y,0  ;move to recorded position
    invoke LineTo,@hDc,m_dragX,m_dragY ;earase last line
   .endif

   invoke MoveToEx,@hDc,m_X,m_Y,0 ;move to recorded position
   mov ebx,lParam  ;draw line to mouse current position
   and ebx,0000FFFFH
   mov m_dragX,ebx
   mov ebx,lParam
   shr ebx,00000010H
   mov m_dragY,ebx
   invoke LineTo,@hDc,m_dragX,m_dragY
   mov m_f,1  ;the first mouse down happened

   invoke SetROP2,@hDc,R2_NOP
   invoke ReleaseDC,hWnd,@hDc
  .endif
;**************************************************************************************
 .elseif eax == WM_LBUTTONUP
  invoke GetDC,hWnd
  mov @hDc,eax
  invoke MoveToEx,@hDc,m_X,m_Y,0 ;move to recorded position

  mov esi,offset m_data  ;record the start point to m_data
  mov eax,m_pdata
  sal eax,2
  add esi,eax
  mov ebx,m_X
  mov [esi],ebx
  inc m_pdata
  mov esi,offset m_data
  mov eax,m_pdata
  sal eax,2
  add esi,eax
  mov ecx,m_Y
  mov [esi],ecx
  inc m_pdata

  mov ebx,lParam  ;get mouse current position
  and ebx,0000FFFFH
  mov m_X,ebx
  mov ebx,lParam
  shr ebx,00000010H
  mov m_Y,ebx
  invoke LineTo,@hDc,m_X,m_Y

  mov esi,offset m_data  ;record the end point to m_data
  mov eax,m_pdata
  sal eax,2
  add esi,eax
  mov ebx,m_X
  mov [esi],ebx
  inc m_pdata
  mov esi,offset m_data
  mov eax,m_pdata
  sal eax,2
  add esi,eax
  mov ecx,m_Y
  mov [esi],ecx
  inc m_pdata

  invoke ReleaseDC,hWnd,@hDc
  xor m_isLine,1  ;left button up
  invoke ReleaseCapture
;**************************************************************************************
 .elseif eax == WM_PAINT
  invoke BeginPaint,hWnd,addr @stPs
  mov @hDc,eax

  mov edi,0
  mov esi,0
  mov ebx,offset m_data
  .while edi < 1024
   mov esi,edi
   mov ecx,[ebx+esi]
   mov @a1,ecx
   mov ecx,[ebx+esi+4]
   mov @a2,ecx
   mov ecx,[ebx+esi+8]
   mov @a3,ecx
   mov ecx,[ebx+esi+12]
   mov @a4,ecx

   invoke MoveToEx,@hDc,@a1,@a2,0 ;move to recorded position
   invoke LineTo,@hDc,@a3,@a4

   add edi,16
  .endw

  invoke EndPaint,hWnd,addr @stPs
;**************************************************************************************
 .elseif eax == WM_CLOSE
  invoke DestroyWindow,hWinMain
  invoke PostQuitMessage,NULL
;**************************************************************************************
 .else
  invoke     DefWindowProc,hWnd,uMsg,wParam,lParam
  ret
 .endif
;**************************************************************************************
 xor        eax,eax
 ret

_ProcWinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
  local      @stWndClass:WNDCLASSEX
  local      @stMsg:MSG

 invoke GetModuleHandle,NULL
 mov hInstance,eax
 invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
 mov m_isLine,0
 mov m_X,0
 mov m_Y,0
 mov m_dragX,0
 mov m_dragY,0
 mov m_f,0
 invoke RtlZeroMemory,offset m_data,sizeof m_data
 mov m_pdata,0
;**************************************************************************************
;  Reg Window Class
;**************************************************************************************
 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
 mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
 mov @stWndClass.lpszClassName,offset szClassName
 invoke RegisterClassEx,addr @stWndClass
;**************************************************************************************
;  Create and Show Window
;**************************************************************************************
 invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,/
  offset szCaptionMain,WS_OVERLAPPEDWINDOW,100,100,600,400,/
  NULL,NULL,hInstance,NULL
 mov hWinMain,eax
 invoke ShowWindow,hWinMain,SW_SHOWNORMAL
 invoke UpdateWindow,hWinMain
;**************************************************************************************
;  Message Loop
;**************************************************************************************
 .while TRUE
  invoke GetMessage,addr @stMsg,NULL,0,0
  .break .if eax == 0
  invoke TranslateMessage,addr @stMsg
  invoke DispatchMessage,addr @stMsg
 .endw
 ret
_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
 call _WinMain
 invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 end start


最后补充一点,Win32汇编编程跟其他语言最大的不同就是:什么都要自己调用系统API,而且各API对各个标志位和寄存器的影响一定要注意,我一开始在刷新时候用的edx做循环判断,但程序只能刷出第一条线,白思不得其解,后来用调试器发现MoveToEx,LineTo返回后会影响edx,晕,而edi是一直空闲的,所以改用edi。所以调试工具一定不能少,不然的话,那编程就象在碰运气了。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值