[资料 from asm.yeah.net] 用TASM写最简单的窗口程序

来源(Iczelion 的 Win32asm 教程)

[资料 from asm.yeah.net] 用TASM写最简单的窗口程序

作者:罗云彬·发布日期:2000-4-1·阅读次数:5484

在这里下载本文的源代码

概述:

用汇编编制一般的 Windows 程序需要的不是汇编编程的资料,而是 Windows 函数调用的资料,你分析一下下面的源程序就会发现,程序的结构跟用 BC++ 编 Windows 程序几乎一模一样,原来用 C++ 函数的地方,变成了一个 Call 外部子程序,而函数的参数是由 PUSH 指令先压入堆栈,先由最后一个参数压起。同样,用汇编编 Windows 程序也需要 .DEF 文件和 .RES 文件,这是由 Windows 程序的结构决定的。本文是一个最简单的 Windows 程序,仅仅开了一个窗口,说一句话:"Hello, Windows 95!",这个声音文件是我从别的地方拷来的,你可以把它换成其他声音文件。
用于编译的工具请到软件下载中找,本文要用到的是 Tasm.exe,Tlink.exe,Make.exe 和库文件 Import32.lib。这儿是源程序和编译好的可执行文件的压缩档:Hellowin.zip

源程序:

文件 Makefile 的内容,这个文件是给 Make.exe 用的,告诉它用什么库文件,什么 .RES 文件等等:

NAME = hellowin
OBJS = $(NAME).obj
DEF = $(NAME).def
RES = $(NAME).res
IMPORT=IMPORT32
$(NAME).EXE: $(OBJS) $(DEF)
   tlink32 /Tpe /aa /c $(LINKDEBUG) $(OBJS),,, $(IMPORT), $(DEF),
.asm.obj:
   tasm32 /ml /m2 $&.asm,,,


文件 Hellowin.def 的内容,同编 C++ 程序一样,定义了数据段,代码段的属性等内容:

NAME HELLOWIN
DESCRIPTION '(C) Copyright by Lyb'
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
EXETYPE WINDOWS
HEAPSIZE 8192
STACKSIZE 8192
EXPORTS WndProc


这里是HelloWin 的源程序:

        .486p
        .model  flat,STDCALL
include windows.inc        ;外部子程序,常量的定义等

;**************************************************
        .data
msg             MSGSTRUCT        ;消息
wndclass        WNDCLASS        ;Windows 类
ptstr           PAINTSTRUCT        ;用于屏幕刷新的句柄
rect            RECT            ;
h_dc            dd    ?        ;DC 句柄,用于屏幕刷新的句柄
h_inst          dd    ?        ;handle of module
h_win           dd    ?        ;handle of window
d_class         db    "hello win",0
t_title         db    "Hello, windows 95 !",0
t_copy          db    'A copy of program is already running, continue ? ',0
paint_x         dd    ?
paint_y         dd    ?
wav_filename    db    'hellowin.wav',0
;**************************************************
        .code
start:
        push    0
        call    GetModuleHandle        ;取模块句柄
        mov     h_inst,eax
find_class:
        push    0
        push    offset d_class
        call    FindWindow        ;查找有无程序副本在运行
        or      eax,eax
        jz      register_class
        push    MB_YESNO or MB_ICONQUESTION
        push    offset t_title
        push    offset t_copy
        push    0
        call    MessageBox        ;显示一个对话框
        cmp     eax,IDNO
        jz      end_loop
register_class:
        push    IDC_ARROW
        push    0
        call    LoadCursor        ;装入光标
        mov     wndclass.clsHCursor,eax
        mov     wndclass.clsStyle,CS_HREDRAW or CS_VREDRAW
        mov     wndclass.clsLpfnWndProc,offset WndProc
        mov     wndclass.clsCbClsExtra,0
        mov     wndclass.clsCbWndExtra,0
        mov     eax,h_inst
        mov     wndclass.clsHInstance,eax
        mov     wndclass.clsHIcon,0
        mov     wndclass.clsHbrBackground,COLOR_WINDOW+1
        mov     wndclass.clsLpszMenuName,0
        mov     wndclass.clsLpszClassName,offset d_class
        push    offset wndclass
        call    RegisterClass        ;注册窗口类
; create new window
        push    0
        push    h_inst
        push    0
        push    0
        push    CW_USEDEFAULT
        push    CW_USEDEFAULT
        push    CW_USEDEFAULT
        push    CW_USEDEFAULT
        mov     eax,WS_OVERLAPPEDWINDOW or WS_MINIMIZE
        push    eax
        push    offset t_title
        push    offset d_class
        push    0
        call    CreateWindowEx        ;创建一个窗口
        mov     h_win,eax

; show new window
        push    SW_SHOWNORMAL
;       push    SW_SHOWMINNOACTIVE    ;show in task bar
        push    h_win
        call    ShowWindow        ;显示窗口

        push    h_win
        call    UpdateWindow        ;刷新窗口
msg_loop:
        push    0
        push    0
        push    0
        push    offset msg
        call    GetMessage        ;取消息循环
        cmp     ax,0
        jz      end_loop

        push    offset msg
        call    TranslateMessage    ;把消息传给 WndProc 子程序
        push    offset msg
        call    DispatchMessage
        jmp     msg_loop
end_loop:
        push    msg.msWPARAM
        call    ExitProcess

;********************************************************************
;    WndProc
;消息处理程序
;********************************************************************
WndProc proc    uses ebx edi esi,hwnd:DWORD,wmsg:DWORD,wparam:DWORD,lparam:DWORD
        LOCAL   theDC:DWORD

;注意,以上的结构是固定的,因为 Windows 自己回先把 EBX,EDI,ESI 压入 STACK
        mov     eax,wmsg
        cmp     eax,WM_CREATE    ;判断消息类型并执行响应程序
        jz      wm_create
        cmp     eax,WM_DESTROY
        jz      wm_destroy
        cmp     eax,WM_PAINT
        jz      wm_paint

        push    lparam        ;return with default windows proc
        push    wparam
        push    wmsg
        push    hwnd
        call    DefWindowProc
        ret
wm_create:
        push    20000h or 1    ;snd_filename | snd_async
        push    0
        push    offset wav_filename
        call    PlaySound
        xor     eax,eax
        ret
wm_paint:
        push    offset ptstr
        push    hwnd
        call    BeginPaint
        mov     h_dc,eax

        push    offset rect
        push    hwnd
        call    GetClientRect

        push    20h or 1 or 4     ;dt_singleline | dt_enter | DT_VCENTEr
        push    offset rect
        push    -1
        push    offset t_title
        push    h_dc
        call    DrawText

        push    offset ptstr
        push    hwnd
        call    EndPaint
        xor     eax,eax
        ret
wm_destroy:
        push    0
        call    PostQuitMessage
        xor     eax,eax
        ret

WndProc endp
public  WndProc
        ends
        end    start

Link: http://www.asm32.net/article_details.aspx?id=2615


浏览次数 313 发布时间 2007-02-22 22:34:14 从属分类 Win32汇编编程 【评论】【 】【打印】【关闭
 
| www.asm32.net | 2006版 | 资料中心 | linux | asm/asm32 | C/C++ | VC++ | java | Python | 书签 | ASP.Net书签 | 京ICP备09029108号-1