Win32汇编学习笔记(四)

简介:
前面几篇文章中都没有使用到菜单,对话框等资源,这次就演练如何在应用程序中加入这些资源。我们就以将VC6.0默认生成的Win32程序移植为32位汇编为例。
首先用VC6.0生成一个默认Win32版的Hello,World程序,将Hello.rc,demo.ico,small.ico都拷贝到项目目录下,去掉VC6.0相关的部分,最后Hello.rc修改如下:
//Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define IDR_MAINFRAME                    128
#define IDD_DEMO_DIALOG        102
#define IDD_ABOUTBOX                    103
#define IDS_APP_TITLE                    103

#define IDM_ABOUT                        104
#define IDM_EXIT                        105
#define IDS_HELLO                        106
#define IDI_DEMO                107
#define IDI_SMALL                        108
#define IDC_DEMO                109

#define IDC_MYICON                        2
#define IDC_STATIC                        -1

/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.

IDI_DEMO       ICON    DISCARDABLE     "demo.ICO"
IDI_SMALL               ICON    DISCARDABLE     "SMALL.ICO"
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDC_DEMO MENU DISCARDABLE
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "E&xit",                IDM_EXIT
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&About ",           IDM_ABOUT
    END
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDC_DEMO ACCELERATORS MOVEABLE PURE
BEGIN
    "?",            IDM_ABOUT,              ASCII,  ALT
    "/",            IDM_ABOUT,              ASCII,  ALT
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOG DISCARDABLE  22, 17, 230, 75
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "About"
FONT 8, "System"
BEGIN
    ICON            IDI_DEMO,IDC_MYICON,14,9,16,16
    LTEXT           "HelloApp 1.0",IDC_STATIC,49,10,119,8,SS_NOPREFIX
    LTEXT           "Copyright (C) 2008",IDC_STATIC,49,20,119,8
    DEFPUSHBUTTON   "OK",IDOK,195,6,30,11,WS_GROUP
END

/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE DISCARDABLE 
BEGIN
   IDC_DEMO   "DEMO"
   IDS_APP_TITLE       "demo"
   IDS_HELLO           "Hello World!"
END
/////////////////////////////////////////////////////////////////////////////

然后创建一个MakFile文件,内容如下:
NAME = Hello
OBJS = $(NAME).obj
RES  = $(NAME).res

$(NAME).exe: $(OBJS) $(RES)
    Link /SUBSYSTEM:WINDOWS $(OBJS) $(RES)
$(RES): $(NAME).rc
    rc $(NAME).rc
.asm.obj:
    ml /c /coff $(NAME).asm

最后仿照VC++代码编写汇编代码如下:
        .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


IDR_MAINFRAME            equ        128
IDD_DEMO_DIALOG        equ 102
IDD_ABOUTBOX            equ        103
IDS_APP_TITLE            equ        103
IDM_ABOUT                    equ    104
IDM_EXIT                    equ    105
IDS_HELLO                    equ    106
IDI_DEMO            equ   107
IDI_SMALL                    equ    108
IDC_DEMO            equ    109
IDC_MYICON                equ        2
IDC_STATIC          equ    -1

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .data?
hInstance    dd        ?        ;应用程序句柄
hWinMain    dd        ?        ;窗口句柄
szCaptionMain        db  1024  dup (?)
szText          db  1024  dup (?)

        .const
szClassName    db    'MyClass',0        ;窗口类名称

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;About对话框处理函数
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_About proc uses ebx edi esi,hDlg,uMsg,wParam,lParam
        mov eax,uMsg
        .if eax == WM_COMMAND
            mov eax,wParam
            movzx eax,ax
            .if eax == IDOK
                invoke EndDialog,hDlg,eax
                ;invoke MessageBox,NULL,addr szText,addr szCaptionMain,MB_OK
            .endif
        .elseif eax == WM_INITDIALOG
                mov eax,1
                ret
        .endif
        xor eax,eax  ;这句非常重要,清零eax,相当于返回false
        ret
_About 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_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
            mov    eax,wParam
            movzx    eax,ax
            .if eax == IDM_EXIT
                invoke    DestroyWindow,hWinMain
                invoke PostQuitMessage,NULL
            .elseif eax == IDM_ABOUT
                invoke DialogBoxParam,hInstance,IDD_ABOUTBOX,hWnd,_About,NULL
            .endif
            
;*************************************************************
        .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            
        invoke LoadIcon,hInstance,offset IDI_DEMO
        mov @stWndClass.hIcon,eax
        invoke LoadString,hInstance,IDS_APP_TITLE,addr szCaptionMain,sizeof szCaptionMain
        invoke LoadString,hInstance,IDS_HELLO,addr szText,sizeof szText
        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
        mov @stWndClass.lpszMenuName,offset IDC_DEMO
        invoke    RegisterClassEx,addr @stWndClass            ;注册窗口类
;*************************************************************
; 建立并显示窗口
;*************************************************************
        invoke    CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,addr 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

nmake编译后运行如下图:
2008030801.jpg


本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/03/08/1096798.html,如需转载请自行联系原作者
目录
相关文章
|
存储 编译器 C语言
Win32汇编:各种语句的构造方式
整理复习汇编语言的知识点,以前在学习《Intel汇编语言程序设计 - 第五版》时没有很认真的整理笔记,主要因为当时是以学习理解为目的没有整理的很详细,这次是我第三次阅读此书,每一次阅读都会有新的收获,这次复习,我想把书中的重点,再一次做一个归纳与总结(注:16位汇编部分跳过),并且继续尝试写一些有趣的案例,这些案例中所涉及的指令都是逆向中的重点,一些不重要的我就直接省略了,一来提高自己,二来分享知识,转载请加出处,敲代码备注挺难受的。
|
存储 编译器 C语言
Win32汇编:字符串浮点数运算过程
整理复习汇编语言的知识点,以前在学习《Intel汇编语言程序设计 - 第五版》时没有很认真的整理笔记,主要因为当时是以学习理解为目的没有整理的很详细,这次是我第三次阅读此书,每一次阅读都会有新的收获,这次复习,我想把书中的重点,再一次做一个归纳与总结(注:16位汇编部分跳过),并且继续尝试写一些有趣的案例,这些案例中所涉及的指令都是逆向中的重点,一些不重要的我就直接省略了,一来提高自己,二来分享知识,转载请加出处,敲代码备注挺难受的。
Win32汇编:字符串浮点数运算过程
|
存储 JavaScript Java
Win32汇编:汇编基本知识总结
汇编语言是所有程序设计语言中最古老的,它与计算机机器语言最为接近,通过汇编语言可以直接访问计算机的硬件,能够直接与CPU对话,可以说汇编语言是所有编程语言中语法格式最自由的,但自由的代价就是需要了解计算机体系结构和操作系统的大量细节,每编写一段程序都需要考虑各种硬件的状态,从而导致使用汇编写程序效率非常低.
|
数据安全/隐私保护
Win32汇编:算术与伪指令
每种汇编语言都有进行操作数移位的指令,移位和循环移位指令在控制硬件设备,加密数据,以及实现高速图形运算时特别有用,移位指令也是汇编语言中最具特征的指令集,`移位(Shifting)`的含义是在操作数内向左或向右移动数据位,Intel处理器提供了多种移位指令,具体如下表所示:
|
存储 编译器 API
Win32汇编:过程与宏调用
在计算机领域,堆栈是一个不容忽视的概念,堆栈是一种`后进先出(LIFO,Last-In,First-Out)`的数据结构,这是因为最后压入堆栈的值总是最先被取出,而新数值在执行PUSH压栈时总是被加到堆栈的最顶端,数据也总是从堆栈的最顶端被取出,堆栈是个`特殊的存储区`,主要功能是暂时存放数据和地址,通常用来保护断点和现场.
|
存储 编译器
Win32汇编:算数运算指令总结
汇编中常用的运算符,加减乘除等,另外包括了移位运算等,移位又分为,算数移位,逻辑移位,循环移位,双精度移位等。
|
存储 编译器
Win32汇编:数组与标志位测试总结
整理复习汇编语言的知识点,以前在学习《Intel汇编语言程序设计 - 第五版》时没有很认真的整理笔记,主要因为当时是以学习理解为目的没有整理的很详细,这次是我第三次阅读此书,每一次阅读都会有新的收获,这次复习,我想把书中的重点,再一次做一个归纳与总结(注:16位汇编部分跳过),并且继续尝试写一些有趣的案例,这些案例中所涉及的指令都是逆向中的重点,一些不重要的我就直接省略了,一来提高自己,二来分享知识,转载请加出处,敲代码备注挺难受的。
|
8天前
|
存储 移动开发 C语言
【ARM汇编速成】零基础入门汇编语言之指令集(三)
【ARM汇编速成】零基础入门汇编语言之指令集(三)
|
8天前
|
编译器 C语言 计算机视觉
【ARM汇编速成】零基础入门汇编语言之指令集(二)
【ARM汇编速成】零基础入门汇编语言之指令集(二)
|
5月前
|
存储 Unix 编译器
汇编语言----X86汇编指令
汇编语言----X86汇编指令
182 2