Win32汇编开发环境介绍和RadAsm简明教程[二]

  好了,上面介绍了win32Asm的开发环境,到底怎么上手呢?我并无意将自己的嗜好强加于各位读者,但还是建议用RadAsm来入门Win32Asm的IDE,没有其它原因,只因为简单好用而且功能强大,等自己熟悉它之后再试试其它AsmIDE也不迟。令我奇怪的是下载的RadAsm并没有自带帮助文件,而要自己单独下载,以至于我一开始的时候更本无法上手,只能慢慢地摸索才知道它的很多的功能。下面我将会用RadAsm2.2.0.1来介绍RadAsm的简单使用,更多的功能就等待你去发掘了。
(1):代码编辑区,大家可以看见,所有关键字着色,当然配色是可以改的,编辑区除了有普通文本编辑的功能外,它还有列选择和过程隐藏功能,例如图片中的“SetAlphaWindow”过程名的最左边有一个“-”号的框,可以单击它来隐藏具体代码或显示所有文本。Ctrl+B进行列选择、Crtl+E展开所有的模块、Shift+F8下书签。
(2):这就是API函数自动检索,这一个功能相信大家都不会陌生了,例如图片中我键入了“SetWindow”后,自动列出所有以SetWindow开头的API函数。上下键进行函数选择,按下“Tab”键自动键入所选的函数。
(3):这一个小小框很有用啊,它完整地列出了API函数原型,当你的鼠标在一个函数上的时候它就显示改函数的原型。菜单“View”->“Info tool”可以显示或隐藏该窗口。
(4):这是一个输出窗口,在编译程序时它输出编译信息,如果有错的话会提示那里错了(显示行号),错了什么(错误信息),这里实质是各个编译器的输出信息,因编译器的不同而不同。菜单“View”->“Output Window”或 工具栏的图标可以显示或隐藏该窗口
(5):纯粹显示行号,可以隐藏它。
(6):从左到右3个按钮的功能为:1:显示或隐藏行号;2:展开所有模块;3:隐藏所有模块,大家都知道汇编程序通常都很长,动不动就有千行的代码,在这么长的代码中找到一个函数模块并不是一件很快的事,这时我们就可以利用2、3的功能来方便我们查看代码:
(7):这里标出了当前打开的窗口,可以利用F6浏览下一个窗口,Alt+1。。9切换到从左数起的第N个窗口,例如只有3个窗口,则可以按下Alt+1切换到从左边数起的第一个窗口。
(8):这是工程管理窗口,每建立一个程序都有一个工程文件,将代码文件和资源文件分开管理,类似于VB的工程管理窗口。在这里可以为工程添加和删除文件或资源。
(9):这是工程属性窗口,如果当前在编辑代码,则它列出代码中的所有函数名,双击列表中的函数名可以直接跳到该函数的首行。如果要查看代码中有那些常数定义和结构定义可以其上的下拉列表框中选择。
(10):这三个按钮就是大名鼎鼎的:编译、编译&连接、运行按钮。编译按钮只编译代码文件,不编译资源文件;编译&连接按钮则同时编译汇编文件、资源文件、和进行连接成Exe文件;运行按钮不用介绍了吧(傻B都知道^_^)。忘了圈第四个按钮了,就在运行按钮的右边(感叹号右边),这个按钮则一次搞定所有的工作:编译代码文件、连接obj文件和Res文件、如果其中没错的话则运行程序,如果任何一项有错都会停止而提示错误信息。几个快捷键是:
          Shift+F5                 编译资源文件(即编译Rc文件为Res文件)
          F5                            编译ASM文件
          Alt+Ctrl+F5          连接文件
          Alt+Shift+F5        编译与连接
          Alt+F5                    编译、连接、运行
          Ctrl+Shift+F5              运行程序
RadAsm安装和配置
现在对RadAsm应该有一点认识了吧,下面介绍RadAsm的安装和环境的配置问题,本节的最后用一个简单的小程序来测试我们的IDE是否配置妥当。
呵呵,其实RadAsm根本不用安装,下载到的是一个压缩包,直接把它解压缩到一个文件夹中就可以了,为了讲解的方便,我以自己的配置为例:系统是Win2000-Pro,RadAsm的版本是2.2.0.1,我把RadAsm解压缩到F:\Asm\ RadASM22en\ 文件夹中;汇编编译器为Masm32V8.2, 下载后也是一个自解压文件,我把它解压到F:\Asm\masm32\ 文件夹中。如果你下载了RadAsm的语言包,则可以把它解压到RadAsm22en 文件夹中。好了,安装RadAsm就是这样简单的了,基本上没什么注意的地方。
现在讲讲RadAsm的配置,进入RadAsm22en 文件夹,运行RadAsm.exe 。如果打开后是英文界面而你又想使用中文,则可以通过菜单:OptionàLanguageà 选择“简体中文”,然后单击“Ok”按钮来切换到中文界面:
下面的讲解都会以中文界面为准,虽然这样做有可能会因为各中文翻译有所不同而造成中文显示不同,但相信大家都能理解其中的意思。
       我们首要的任务是配置MASM32,单击菜单 选项à路径设置,在弹出的对话框中即可设置汇编编译器的路径:
最重要的是设置好masm32的路径,只要该路径设置好,整个开发环境就可以立即工作了。
可见RadAsm的安装和配置都很简单,为了验证我们配置的环境能否正常工作,下面做一个只显示一个对话框的程序来进行测试。单击菜单 文件à新建文件 或按快捷键 Ctrl+N,在代码编辑窗口中键入如下的代码:(注意大小写敏感)
完成后我把代码保存为F:\backupDoc\test.asm,然后再单击菜单 构建àGo All,如图所示:
如果大家还记得的话,就知道这是编译、连接、运行一次搞定的选项,当编译器路径没有配置错误,程序即会进行编译、连接和运行。如图所示:
至于汇编代码我就不解析了,也不是本教程的范围。如果编译期间发生了错误,则可以在输出窗口中查看错误提示,一般第一次的错误都是没有设置好Masm32的路径。如果没错的话RadAsm会显示整个编译和连接的过程,如上面的程序就输出如下信息:
F:\Asm\masm32\Bin\ML.EXE /c /coff /Cp /nologo /I"F:\Asm\masm32\Include" "F:\backupDoc\test.asm"
      Assembling: F:\backupDoc\test.asm
F:\Asm\masm32\Bin\LINK.EXE /SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0 /LIBPATH:"F:\Asm\masm32\Lib" "F:\backupDoc\test.obj" 
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
Executing:
      "F:\backupDoc\test.exe"
Make finished.
Total compile time 1693 ms
可以从上面的示例知道,用RadAsm集成开发环境一点也不比那些高级语言的IDE逊色,用RadAsm也比自己手工编辑makefile要简单的多,用它来练习Iczelion和罗云彬的教程是很不错的选择。
RadAsm开发标准窗口程序
开发窗口程序主要有两种方式,一种是创建标准的窗口程序,这过程需要先填充WNDCLASSEX结构,然后则是注册窗口à创建窗口à显示窗口à进入消息循环à对消息进行处理;另一种更为常用的是基于对话框的窗口,这种方式首先建立资源文件,资源包括对话框、各类标准控件、图标、光标、BMP文件等,如果用过Vc的朋友就一定不会陌生了,建立好资源后将资源编译成RES文件,然后在程序中使用各种资源,这种方式的好处是省去了建立标准窗口的步骤,而且对话框也是与用户进行交互的主要工具,程序员也可以集中关注程序功能而不必花太多时间在界面上。
这一节主要讲怎样利用RadAsm建立工程,编写标准的窗口程序。为了更直观地讲解RadAsm的使用,我将会以Iczelion的Win32Asm教程上第四讲的例子绘制文本为例建立一个RadAsm工程。你将会看到,除了单击下一步外,剩下需要做的只是 粘贴代码à 按一下工具栏上的“go all”按钮来编译、连接、运行程序。一切将会简单而易行。
好了,我们现在打开RadAsm,单击菜单 文件à新建工程,在弹出的对话框中设置好工程名和工程的类型,如下图所示:
由于工程类型的选择影响到整个程序的编译和连接,所以大家在选择时不可以随便选一个类型就完事了。下面列出几个常用的工程类型:
1:如果要开发一个带有资源的标准窗口程序,则选择Win32App类型,
  假如程序要用到对话框、图标、菜单、快捷键等的话就应该选择这个类型。
2:如果要开发一个没有资源的标准窗口程序,则选择Win32App(No Resource) 类型,一般不用资源的情况很少,但本节用来测试的例子就是一个没有资源的标准窗口程序。
3:如果要开发一个Windows下的控制台程序,则应选择Console APP 。
4:如果只开发一个Dll,则应选择Dll project类型。
设置好后单击“下一步”按钮;现在程序问你是否使用模板,这要看具体做什么程序了,如建立标准窗口程序可以使用“WIN32EXE.tpl”模板,对话框程序可以使用“DialogApp.tpl”模板。当然可以不使用模板,我们现在就这么做,在模板选项中单击“None”选项,然后单击“下一步”按钮。来到这里我们可以设置需要那些类型的文件和文件夹,当然,“ASM”文件是必选的,其它有用的选项我们在讲解对话框程序时再述。再次单击“下一步”按钮,设置如下图所示:
好了,大家都可以看到工程向导到这里就完成了,单击“完成”按钮吧。
现在工程就建立完成了,是不是很容易?嗯!现在看看开发窗口右边的工程管理器窗口,我们刚才建立的工程生成了一个“DrawText.Asm”文件,该文件就是主代码文件了,我们可以双击它来打开代码编辑窗口:
现在呢,实现我之前的诺言吧:把Iczelion的Win32Asm教程上第四讲的例子代码粘贴过来,如果格式不好自己再整理一下;考虑到有些朋友手头上暂时没有该例子的代码,没有的朋友可以直接复制下面的文本到RadAsm的代码编辑窗口中:
.386 
.model flat,stdcall 
option casemap:none 

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD 

include       windows.inc 
include       user32.inc 
includelib    user32.lib 
include       kernel32.inc 
includelib    kernel32.lib 

.DATA 
ClassName db "SimpleWinClass",0 
AppName  db "Our First Window",0 
OurText  db "Win32 assembly is great and easy!",0 

.DATA? 
hInstance HINSTANCE ? 
CommandLine LPSTR ? 

.CODE 
start: 
    invoke GetModuleHandle, NULL 
    mov    hInstance,eax 
    invoke GetCommandLine
    mov CommandLine,eax
    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT 
    invoke ExitProcess,eax 

WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD 
    LOCAL wc:WNDCLASSEX 
    LOCAL msg:MSG 
    LOCAL hwnd:HWND 
    mov   wc.cbSize,SIZEOF WNDCLASSEX 
    mov   wc.style, CS_HREDRAW or CS_VREDRAW 
    mov   wc.lpfnWndProc, OFFSET WndProc 
    mov   wc.cbClsExtra,NULL 
    mov   wc.cbWndExtra,NULL 
    push  hInst 
    pop   wc.hInstance 
    mov   wc.hbrBackground,COLOR_WINDOW+1 
    mov   wc.lpszMenuName,NULL 
    mov   wc.lpszClassName,OFFSET ClassName 
    invoke LoadIcon,NULL,IDI_APPLICATION 
    mov   wc.hIcon,eax 
    mov   wc.hIconSm,eax 
    invoke LoadCursor,NULL,IDC_ARROW 
    mov   wc.hCursor,eax 
    invoke RegisterClassEx, addr wc 
    invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\ 
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ 
           CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\ 
           hInst,NULL 
    mov   hwnd,eax 
    invoke ShowWindow, hwnd,SW_SHOWNORMAL 
    invoke UpdateWindow, hwnd 
        .WHILE TRUE 
                invoke GetMessage, ADDR msg,NULL,0,0 
                .BREAK .IF (!eax) 
                invoke TranslateMessage, ADDR msg 
                invoke DispatchMessage, ADDR msg 
        .ENDW 
        mov     eax,msg.wParam 
        ret 
WinMain endp 

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
    LOCAL hdc:HDC 
    LOCAL ps:PAINTSTRUCT 
    LOCAL rect:RECT 
    .IF uMsg==WM_DESTROY 
        invoke PostQuitMessage,NULL 
    .ELSEIF uMsg==WM_PAINT 
        invoke BeginPaint,hWnd, ADDR ps 
        mov    hdc,eax 
        invoke GetClientRect,hWnd, ADDR rect 
        invoke DrawText, hdc,ADDR OurText,-1, ADDR rect, \ 
                DT_SINGLELINE or DT_CENTER or DT_VCENTER 
        invoke EndPaint,hWnd, ADDR ps 
    .ELSE 
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam 
        ret 
    .ENDIF 
    xor   eax, eax 
    ret 
WndProc endp 
end start 
好了,跟着就是编译、连接、运行了,还记得快捷键吗?按下Alt+F5 吧,一切顺利的话,程序会被运行,如下图所示:
值得一提的是原Iczelion的Win32Asm教程上第四讲的例子代码中包含头文件和库都是使用绝对路径的(代码中橙色的部分表示已进行过修改),而我们的RadAsm早已设置好路径,所以工程里不需要那样做,我做了如下改动:
原代码:

include \masm32\include\windows.inc 
include \masm32\include\user32.inc 
includelib \masm32\lib\user32.lib 
include \masm32\include\kernel32.inc 
includelib \masm32\lib\kernel32.lib

修改为(以后其它的例子也是这样,不必包含绝对路径):

include       windows.inc 
include       user32.inc 
includelib    user32.lib 
include       kernel32.inc 
includelib    kernel32.lib 

用RadAsm开发程序就是这样简单,同样,如果你正在学习罗云彬的Win32Asm教程,可以直接用RadAsm来做书上的所有例子(我就是这么做的),这样比该书原书介绍的方法来的更简单和快速。
RadAsm开发基于对话框的程序
       基于对话框的程序我们平常见得很多,如windows自带的计算器就是一个对话框程序。如果只学过VB的朋友可能并不了解资源,因为每新建一个工程总会有一个窗口给你,然后就是添加控件和编写处理事件的代码,平时完全接触不到资源的概念;但学VC的不同,如果要一个对话框就必须自己建立对话框资源,然后再在程序里通过装载资源来使用。在这里不会再解析什么是资源的问题,只关心如何在RadAsm里建立各种资源。RadAsm强大的其中一个原因就是它整合了资源编辑功能,而不必再借助第三方工具。

       本节将会向大家介绍RadAsm的资源编辑功能,我们将创建一个有三个文本框、三个标签和两个按钮的对话框程序,程序的功能是在其中两个文本框中输入文本,然后通过单击按钮将输入的文本一起输出到第三个文本框中,单击退出按钮退出程序。

       好了,现在打开RadAsm,单击菜单 文件à新建工程,在向导中选择工程类型为 Win32App,把工程名称和工程描述都填写为 “DialogApp”,然后单击“下一步”按钮;现在是模板选择向导,我们选择(None),然后单击“下一步”按钮;来到了选择需要创建那些文件,在“生成文件”选项中选中“ASM”和“RC”,然后在“生成文件夹”选项中选中“Res”,如下图所示:


在最后的构建向导中设置如下图所示:(只需勾选“菜单构建”项,其它默认即可)
最后当然是单击“完成”按钮来结束向导了。现在在工程管理窗口中可以看到程序为我们创建了一个DialogApp.Asm文件和一个DialogApp.Rc资源文件。如下图所示:
现在右键单击“DialogApp.Rc”,在弹出的菜单中选择“添加”à“对话框”菜单,如下图所示:
紧跟着会弹出一个要求保存对话框资源文件的对话框,双击“Res”文件夹,我们把对话框资源文件保存在里,在文件名中填上“DlgApp”作为资源文件名。之后程序会自动切换到资源编辑界面,这里就是RadAsm自带的资源编辑界面了,如图所示:  
好了,相信大家对这个环境还是比较熟眼的,下面就是添加和修改各控件的属性了,先修改对话框本身吧,设置如下的属性:

对话框属性名
设置值

Name
IDD_DLG_MAIN

Caption
好一个对话框程序

MaxButton
False

Font
Tahoma

StartupPos
CenterScreen


其它的属性默认即可。

接着我们添加三个文本框、三个标签、两个按钮,分别设置如下属性:

文本框1属性名
设置值

Name
IDC_EDT_FIRST

AutoScroll
Horizontal
文本框2属性名
设置值
Name
IDC_EDT_SECOND

AutoScroll
Horizontal
文本框3属性名
设置值
Name
IDC_EDT_OUTPUT

AutoScroll
Both

MultiLine
True

ScrollBar
Both

标签1属性名
设置值

ID
-1

Caption
第一个字符串:

标签2属性名
设置值
ID
-1

Caption
第二个字符串:
标签3属性名
设置值

ID
-1

Caption
输出字符串:

按钮1属性名
设置值

Name
IDC_BTN_OUTPUT

Caption
输出(&O)
按钮2属性名
设置值

Name
IDC_BTN_EXITAPP

Caption
退出(&E)

整个对话框最后设计成下图所示:


如果想预览一下对话框的运行效果可以单击工具栏上的 按钮来进行。整个界面设计好后别忘了保存,直接按“Ctrl+S”就可以。
好了,整个对话框资源就建立好了,是时候编程了,程序的流程是先获取两个文本框的文本,然后通过单击“输出”按钮来一并输出到第三个文本框中,是否觉得过于简单?是的,我们现在的目的不是编写功能如何强大的程序,而是熟悉RadAsm的资源编辑环境。

在工程管理窗口双击“DialogApp.Asm”进入代码编辑窗口,为了方便,我直接给出代码,大家只要将代码复制到编辑窗口里就可以了:
.386

.model flat, stdcall

option casemap:none



include         windows.inc

include         user32.inc

include         kernel32.inc



includelib     user32.lib

includelib     kernel32.lib



.const

;利用我自己编写的DefToEqu程序转化的常数ID。

IDD_DLG_MAIN           equ 1000

IDC_EDT_OUTPUT              equ 1003

IDC_EDT_FIRST           equ 1001

IDC_EDT_SECOND             equ 1002

IDC_BTN_OUTPUT              equ 1004

IDC_BTN_EXITAPP             equ 1005



.data

       szExitApp    db   "你真的要退出程序吗?",0

       szTitle          db   "好一个对话框程序",0

       ;将两个字符串合并为一个的格式化字符串。

       szFormat      db   "%s%s", 0

       

       hInstance     dd   ?     ;程序实例句柄

       

.code



DlgProc  proc  uses ebx esi edi hwnd, uMsg, wParam, lParam

       

       ;定义了三个局部数组,类型均为字节型

       LOCAL @szBuffer1[256]:byte

       LOCAL @szBuffer2[256]:byte

       LOCAL @szOutputBuf[512]:byte

       

       mov       eax, uMsg

       .if    eax == WM_INITDIALOG   

              ;这里编写窗口初始化的代码,下面是将三个局部数组清零

              invoke  RtlZeroMemory, addr @szBuffer1, sizeof @szBuffer1

              invoke  RtlZeroMemory, addr @szBuffer2, sizeof @szBuffer2

              invoke  RtlZeroMemory, addr @szOutputBuf, sizeof @szOutputBuf

              

       .elseif eax == WM_COMMAND

              mov       eax, wParam

              .if   ax == IDC_EDT_FIRST

                     ;这里编写处理第一个文本框的代码

                     

              .elseif    ax == IDC_EDT_SECOND

                     ;这里编写处理第二个文本框的代码

                     

              .elseif    ax == IDC_BTN_OUTPUT

                     ;先获取两个文本框的文本,分别保存在@szBuffer1和@szBuffer2中

                     ;然后通过格式化函数wsprintf将两个文本合并,最后输出到第三个文本框中。

                     invoke  GetDlgItemText, hwnd, IDC_EDT_FIRST, addr @szBuffer1, sizeof @szBuffer1

                     invoke  GetDlgItemText, hwnd, IDC_EDT_SECOND, addr @szBuffer2, sizeof @szBuffer2

                     invoke  wsprintf, addr @szOutputBuf, addr szFormat, addr @szBuffer1, addr @szBuffer2

                     invoke   SetDlgItemText, hwnd, IDC_EDT_OUTPUT, addr @szOutputBuf

                     

              .elseif    ax == IDC_BTN_EXITAPP

                     invoke  SendMessage, hwnd, WM_CLOSE, 0, 0

                     

              .endif

              

       .elseif    eax == WM_CLOSE

              ;这里处理程序退出代码

              invoke  MessageBox, hwnd, addr szExitApp, addr szTitle, MB_ICONQUESTION or MB_YESNO

              .if    al == IDYES

                     invoke  EndDialog, hwnd, NULL

              .endif

                     

       .else

              mov       eax, FALSE

              ret

       .endif

       

       mov       eax, TRUE

       ret



DlgProc endp



;程序入口点

start:

       ;获取实例句柄

       invoke   GetModuleHandle, NULL

       mov       hInstance, eax

       ;调用对话框函数来显示对话框。

       invoke  DialogBoxParam, hInstance, IDD_DLG_MAIN, NULL, offset DlgProc, NULL

       invoke  ExitProcess, NULL

end start
好了,现在就等着你按下“Alt+F5”了,如果一切顺利的话立即可以看到程序运行,如下图所示:
现在你知道RadAsm的魅力了吧,建立资源一点都不比Vc慢,而且更简单直观。由于篇幅问题,如何建立菜单、图标和其它控件就不再一一介绍了,相信聪明的你下点功夫就能弄明白。后记

这次还是我第一次写这么长(我认为)的教程,以前都是用代码说话,一个完整的源代码加上原理解说就可以了。因为在网上论坛看到很多朋友想学习Win32Asm编程,但无从下手,网上也没有专门关于汇编IDE使用的介绍,所以自己才决定写这份教程,希望能对大家入门汇编IDE有所帮助,由于小弟文笔不是太好,难免文章中出现错漏,希望你能及时通知我,以便及时纠正,让更多朋友受惠。

为了大家更好的学习本教程和避免不必要的错误,我决定将文章中示例的RadAsm22en、文章介绍的三个代码例子和本教程一起打包,放在我的主页上供大家下载。但未经本人同意,不得将本教程用作任何形式的商业行为,如果需要转载的朋友也一定要保证文章的完整性。谢谢。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值