`
deepfuture
  • 浏览: 4442083 次
  • 性别: Icon_minigender_1
  • 来自: 湛江
博客专栏
073ec2a9-85b7-3ebf-a3bb-c6361e6c6f64
SQLite源码剖析
浏览量:80543
1591c4b8-62f1-3d3e-9551-25c77465da96
WIN32汇编语言学习应用...
浏览量:71167
F5390db6-59dd-338f-ba18-4e93943ff06a
神奇的perl
浏览量:104483
Dac44363-8a80-3836-99aa-f7b7780fa6e2
lucene等搜索引擎解析...
浏览量:288278
Ec49a563-4109-3c69-9c83-8f6d068ba113
深入lucene3.5源码...
浏览量:15248
9b99bfc2-19c2-3346-9100-7f8879c731ce
VB.NET并行与分布式编...
浏览量:68821
B1db2af3-06b3-35bb-ac08-59ff2d1324b4
silverlight 5...
浏览量:32760
4a56b548-ab3d-35af-a984-e0781d142c23
算法下午茶系列
浏览量:46459
社区版块
存档分类
最新评论

算法下午茶系列-重温汇编(7)[win32汇编]

 
阅读更多

 

        在WINDOWS系统能用到汇编的机会不多,基本都可以用C或C++代劳,更何况现在MICROSOFT的Visual Studio 系列工具非常强大,WINDOWS下的开发已经在向.NET方面发展,实际调用WINDOWS SDK的机会也不多。 WIN32汇编编写窗口程序需要调用大量的WINDOWS 的API,而且提供了高级语言才有的条件语句和循环语句,难度相对于LINUX下的AT&T汇编要小很多。

因此,在此只简单介绍一下,首先来看一段简单的窗口程序。注意";"表示注释

;加上注释和个人理解


.386
.model flat,stdcall
option casemap:none

;以下定义INCLUDE文件
include winows.inc
include gdi32.inc
includelib gdi32.lib
include user32.inc
includelib user32.lib
include kernel32.inc
include kernel32.lib
;以下定义数据段
.data ? ;定义变量
hinstance dd ?
hwinmain dd ?
.const ;定义常量,字符串全部要以0结尾,因为在内存中0是字符串的结束符
szclassname db 'billclass',0
szcaptionmain db 'bill's firt program',0
sztext db 'WIN32汇编,BILL!!!!',0
;以下是代码段
.code
;定义窗口过程
_procwinmain proc uses ebx edi esi,hwnd,umsg,wparam,lparam
;定义局部变量用关键字local
local @stps:PAINTSTRUCT
local @strect:PAINTSTRUCT
local @hdc
mov eax,umsg ;取得传入过程的消息变量值
;-----------下面开始根据消息类型的不同作出不同的处理
.if eax == WM_PAINT ;如果消息是窗口绘制
invoke BeginPaint,hwnd,addr@stRect;WIN32汇编调用API程序后,API程序将返回值放在EAX中,
;客户区准备
mov @hdc,eax;取得设备句柄

invoke GetclientRect,hwnd,addr @stRect;addr是取变量的地址但只能用在INVOKE语句中且
;不能同时使用
;EAX寄存器传参数,因为ADDR会用到EAX。
;此API的含义是取得描述客户区的结构放在@stRect
invoke drawText,@hdc,addr sztext,-1,addr @stRect,\
DT_SINGLELINE or DT_CENTER or DT_VCENTER ;语句换行符是\,显示'WIN32汇编,BIL
;L!!!!',并设置其为单行DT_SINGLE
;等等LINE
invoke EndPaint,hwnd,addr @stPs
  .elseifmeax==WM_CLOSE
invoke DestroyWindow,hwinmain ;销毁窗口
invoke PostQuitMessage,Null ;向消息循环中发出退出消息
.else
invoke DefWindowProc,hwnd,uMsg,wPara,lParam;如果不是上述消息,则执行WINDOWS标准的默认消息处
;理,如键盘等消息
ret;返回
.endif

xor eax,eax ;eax清0
ret
_ProcWinMain endp
;以上这个子程序处理窗口消息的,是窗口的回调函数,该项函数不是我们调用,是由WINDOWS调用用来处理
;窗口消息的,我们调用的是DispatchMessage,DispatchMessage再回过头来调用窗口过程。
_WinMain Proc ;主程序
local @stWndClass:WNDCLASSEX
local @stmsg:MSG

invoke GetModuleHandle,Null ;得到应用程序句柄
mov hInstance,eax ;将应用程序的句柄放入hInstance变量
invoke RtlZeroMemory,addr @stWndClass,sizeof WndClassEX ;msdn的解释TheRtlZeroMemory routine
;fills a block of memory with zeros,即
;0填充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;设置回调函数,也就是窗口消息处理过程
mov @stwndclass.hbrbackground,COLOR_WINDOW+1
mov @stwndclass.lpszclassname,offset szclassname ;设置窗口类的名称
invoke RegisterClassEx,addr @stwndclass ;传上述设置好的结构以注册窗口类
 ;建立显示窗口
invoke CreateWindowEx,WS_EX_CLIENTEDGE,\
offset szclassname,offsetszcaptionmain,\
WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,\
NULL,hinstance,NULL ;建立窗口并返回句柄在EAX中
mov hwinMain,eax ;刚创建的窗口句柄赋值
invoke showwindow,hwinmain,SW_SHOWNORMAL ;显示窗口
invoke updatewindow,hwinmain ;刷新窗口客户区,导致客户区窗口paint
;消息循环,win32汇编得自行建立WINDOWS消息循环,不过这样更自由,可以彻底地控制程序
.while true
 invoke GetMessage,addr @stMsg,null,0,0 ;WINDOWS在系统内部有个系统消息队列,
            ;并为每个应用程序还维护了一个消息队列,将这些属于这些程序窗口范围内的
            ;系统消息发到该应用程序消息队伍中,这个API的作用就是从自己的应用程序
            ;消息队伍中接收消息。
  .break .if eax==0 ;If the function retrieves the WM_QUIT message, the return value is zero.
            ;invoke Translate(msdn),也就是说,当程序退出里,消息队伍里会有WM_QUIT消息,            ;就退出循环,意味着退出程序。
  invoke translatemessage,addr @stmsg;由应用程序对消息进行预处理,如把基于键盘扫描码的按键消息黑心                   ;换成ASCII码的键盘消息等
  invoke dispatchmessage,addr@stmsg ;将预处理好的消息发给WINDOWS,WINDOWS将其分派给该程序的相应窗;口处理过程处理,那么WINDOWS怎么知道窗口处理过程在哪呢,刚才不是已经注册过窗口类了,这就是为什么窗口;类要注册的原因了,那么为什么不能由程序自己处理消息,非得发给WINDOWS呢,其一、一个应有程序的窗口很多,如果自己处理的话,得建立一个窗口列表,上面记录每个窗口的窗口处理过程。其二、WINDOWS对于一些实时性很;强的信息采用直接调用窗口处理过程的方法。
.endw
ret
_winmain endp
;没有下面的代码程序无法执行,因为START语句指定程序启动的入口点
start:
call _winmain
invoke ExitProcess,NULL;退出
end start 

 可以看到上面代码和用C编写的WIN SDK程序很相似。我们接着继续看2个例子:

例1:用WIN32汇编构建第一个WINODWS程序,这个程序完成显示一个带问号的对话框,对话框的内容是现在系统时间。

 

 

   首先,打开MASM32Editor(在桌面上可以找到图标),在里面输入以下代码:
     .386
     .model flat, stdcall
     option casemap :none  
;#################################################################
     include windows.inc
     include user32.inc
     include kernel32.inc
     include gdi32.inc
     include masm32.inc
     
     includelib user32.lib
     includelib kernel32.lib
     includelib gdi32.lib
     includelib masm32.lib
;#################################################################
   .data?
      szbuffer db 100 dup(?)
   .data
      szcaptionName db "我的HELLO,WORLD!",0
      szbegin db "现在时间:"
      sztext db 100 dup(?)
;#################################################################  .code
start:
;程序的入口
       call _callgetnow
       invoke MessageBox,NULL,offset szbegin,offsetszcaptionName,MB_ICONQUESTION or MB_OK
       invoke ExitProcess,eax
;#################################################################
_callgetnow proc
    pushad
  invokeGetDateFormat,LOCALE_USER_DEFAULT,DATE_LONGDATE,NULL,NULL,addrsztext,100
    invokeGetTimeFormat,LOCALE_USER_DEFAULT,LOCALE_NOUSEROVERRIDE,NULL,NULL,addrszbuffer,100
   
    invokeszCatStr,addr sztext,addr szbuffer
    popad
    ret
_callgetnow endp
;#################################################################
end start

 

  将上述代码保存为HELLOWORLD.ASM后,对程序进行编译。
  在编译前参照下图设置好系统的环境变量,path变量加上x:\masm32\bin,lib变量加上x:\masm32\lib,include变量加上x:\masm32\include。

  确环境变量设置好后,进入DOS窗口开始编译。

   首先运行ml,编译成coff文件格式
  然后运行LINK,进行链接,生成EXE文件,


  大功造成,运行一下试试效果吧!

 



例2:系统时间直接显示在桌面上。程序源代码如下:
   
.386
     .model flat, stdcall
     option casemap :none  
;#########################################################################
     include windows.inc
     include user32.inc
     include kernel32.inc
     include gdi32.inc
     include masm32.inc
     
     includelib user32.lib
     includelib kernel32.lib
     includelib gdi32.lib
     includelib masm32.lib
;#########################################################################
   .data?
      szbuffer db 100 dup(?)
   .data
      szmssucesscap db "HELLO,WORLD!深入",0
      szmssucesstext db "在桌面的(300,300)处显示了当前时间",0
      szmscap db "错误",0
      szmstext1 db "无法在桌面上显示!",0
      szmstext2 db "无法得到全屏DC!",0
      szbegin db "现在时间:"
      sztext db 100 dup(?)
;#########################################################################
    .code
start:
;程序的入口
       _showtext  proto :DWORD
       call _callgetnow
       invoke _showtext,offset szbegin
       invoke ExitProcess,eax
;#########################################################################
_callgetnow proc
    pushad
  invokeGetDateFormat,LOCALE_USER_DEFAULT,DATE_LONGDATE,NULL,NULL,addrsztext,100
    invokeGetTimeFormat,LOCALE_USER_DEFAULT,LOCALE_NOUSEROVERRIDE,NULL,NULL,addrszbuffer,100
   
    invokeszCatStr,addr sztext,addr szbuffer
    popad
    ret
_callgetnow endp
;#########################################################################
_showtext proc  lpsztext:DWORD
    LOCAL@Desktopdc:HDC
    LOCAL@dwcolor:DWORD
   
    pushad
    mov@dwcolor,00FF0000h
    invokeGetWindowDC,NULL
    cmpeax,0
    jne @f
    invokeMessageBox,NULL,offset szmstext2,offset szmscap,MB_ICONERROR
    @@:
    mov@Desktopdc,eax
    invokelstrlen,lpsztext
    movebx,eax
    invokeSetBkMode,@Desktopdc,TRANSPARENT
    invokeSetTextColor,@Desktopdc,@dwcolor
    invokeTextOut,@Desktopdc,300,300,lpsztext,ebx
    invokeMessageBox,NULL,offset szmssucesstext,offsetszmssucesscap,MB_ICONINFORMATION
    cmpeax,0
    jne @f
    invokeMessageBox,NULL,offset szmstext1,offset szmscap,MB_ICONERROR
    @@:
    popad
    ret
_showtext endp
;#########################################################################
end start
 
 
以上程序中有几个重要的GDI相关的API,下面简要介绍一下
(1)
invoke SetBkMode,@Desktopdc,TRANSPARENT
设置背景方式为透明
(2)
invoke SetTextColor,@Desktopdc,@dwcolor
设置字体颜色为蓝色
(3)
invoke TextOut,@Desktopdc,300,300,lpsztext,ebx
在300,300处显示文本
(4)
invoke GetWindowDC,NULL
取得桌面DC
(5)
mov @dwcolor,00FF0000h
设置颜色为蓝色。@dwcolor是一个DWORD型的变量,
  可以在相关头文件中找到这样的定义:
typedef DWORD COLORREF;
因此COLORREF类型的变量就是DWORD型变量。
 COLORREF变量如何表示颜色呢,只有一个双字大小,它的表示格式是(16进制):
0x00bbggrr
bb表示蓝色,gg表示绿色,rr表示红色
00FF0000h:蓝
0000ff00h:绿
000000FFh:红
扩展阅读 :
《Windows环境下32汇编语言程序设计》  罗云彬
如果转载请注明来源,如有错误之处,请及时指出
分享到:
评论

相关推荐

    openssl-0.9.8k_WIN32(RSA密钥生成工具)

    在本压缩包中,"openssl-0.9.8k_WIN32"指的是OpenSSL的一个特定版本,适用于Windows 32位操作系统。 **RSA密钥生成** RSA是一种非对称加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出。它基于...

    win32汇编语言实现冒泡排序

    基于这样的背景,本文将介绍如何使用Win32汇编语言实现冒泡排序算法。虽然汇编语言的学习曲线较为陡峭,但通过实践可以加深对计算机底层工作原理的理解,并有助于提高程序的执行效率。 #### 二、使用开发环境 - **...

    Ubuntu下的x86-64汇编(x86-64 Assembly Language with Ubuntu)

    - **核心概念**:编写汇编语言程序需要熟悉一系列开发工具,包括编译器、链接器等。 - **实际应用**:通过亲手编写和调试汇编程序,可以增强对整个编译过程的理解。 - **1.3.3 提高算法开发技能** - **核心概念**...

    IBM-PC汇编语言程序设计(第五版)

    ### IBM-PC汇编语言程序设计(第五版)——核心知识点解析 #### 一、书籍简介 《IBM-PC汇编语言程序设计(第五版)》是一部深入浅出地介绍IBM-PC环境下汇编语言程序设计的经典教材。本书旨在帮助读者理解和掌握汇编语言...

    做好的沈美明主编IBM-PC汇编实验详细报告

    IBM-PC汇编是针对IBM个人计算机系列(包括兼容机)的汇编语言,它主要用于对硬件进行直接控制,优化性能关键的代码,以及编写操作系统和设备驱动程序。 **实验报告结构** “做好的沈美明主编IBM-PC汇编实验详细...

    tasm32 Win32汇编 编译器下载

    tasm32 Win32汇编 编译器下载 tasm32是Borland公司开发的Win32汇编编译器,被广泛用于各种等编译器,用作中间过渡编译。它也能独立的编译纯汇编或是Win32Asm的代码。具有编译快速,高效的特点,至今依然是汇编开发...

    Win32汇编程序设计

    在Win32平台上,汇编语言可以用于编写高效的系统级代码、驱动程序、优化的算法以及对硬件进行直接操作的程序。 Win32 API(Application Programming Interface)是Microsoft Windows操作系统提供的一个接口,程序员...

    易语言adler32算法汇编

    Adler-32算法由Bob Jenkins设计,它的全称是“Adler-32 checksum”。这个算法比CRC(Cyclic Redundancy Check)校验稍简单,但仍然能够有效地检测数据错误。它由两个32位的累积器A和B组成,其中A用于记录较小的字节...

    汇编语言代码大全--精通汇编

    7. **汇编与高级语言的交互**:通常,汇编语言会与C/C++等高级语言结合使用,用于编写性能关键的代码段,如启动代码、设备驱动或算法优化。 8. **调试技巧**:学会使用汇编级别的调试工具,如GDB,能帮助你更深入地...

    计算机系统1-汇编语言实验.docx

    本文档是关于计算机系统的汇编语言实验报告,旨在通过 LC-3 汇编语言设计实现相关程序,熟悉和理解 LC-3 的汇编语言指令格式,并掌握在 LC-3 仿真平台下汇编语言代码的设计输入和调试过程。 知识点1:汇编语言基础 ...

    SUN 公司内部培训资料 IA-32 汇编语言手册

    根据提供的文件信息,我们可以推断出这是一份由 SUN Microsystems 出版的关于 IA-32 架构下的汇编语言的手册。这份手册详细介绍了 IA-32 架构下的汇编语言基础、指令集以及相关的编程技术。下面将对这份资料中涉及的...

    Win32汇编课程大作业--矩阵相乘:先后输入存储矩阵的两个文件名,屏幕显示矩阵,后将计算结果输出到指定目标文件中和屏幕显示结果

    在本项目中,我们探讨了如何使用Win32汇编语言编写一个程序,该程序能够实现两个矩阵的相乘,并将结果输出到指定的目标文件以及屏幕。这是一个典型的计算机科学问题,涉及到了数值计算、文件操作以及用户界面交互等...

    IBM-PC 汇编语言课后答案

    根据给定文件的信息,我们可以提炼出关于IBM-PC汇编语言程序设计的多个知识点,主要围绕着《IBM-PC汇编语言程序设计》第二版教材(清华大学沈美明版)中的概念、指令以及编程实践。以下是对这些知识点的详细解析: ...

    清风汇编-易语言汇编学习.rar

    3. **速度优化**:对于计算密集型的代码段,如碰撞检测、AI算法,汇编可以编写出高效且运行速度快的代码。 4. **系统调用**:汇编语言可以方便地调用操作系统提供的底层服务,实现如键盘鼠标模拟、窗口管理等高级...

    天书夜读--汇编语言

    - **算法转换**:展示了如何将高级语言编写的算法转换为汇编代码。 - **优化建议**:给出了针对特定算法进行优化的具体建议。 通过这些详细的解析和示例,读者不仅可以了解到汇编语言的基本语法和结构,还能掌握...

    coreseek-4.1-win32

    在Windows环境下,CoreSeek 4.1版本为开发者提供了在Win32平台上搭建搜索服务的便利。这个压缩包“coreseek-4.1-win32.zip”包含了所有必要的文件,使得用户可以在Windows系统上安装和运行CoreSeek。 **1. CoreSeek...

    IBM-PC汇编语言程序设计

    7. **调试与反汇编**:了解使用汇编语言调试工具,如DEBUG,以及如何将机器码反汇编回汇编语言代码。 8. **高级主题**:书中可能还会涉及高级汇编技术,如宏指令、自定义汇编器宏、堆栈操作、动态内存分配、多任务...

    MATLAB-遗传算法-多车场-开放式-带时间窗-多商品-VRP问题

    《MATLAB实现遗传算法解决多车场开放式时间窗多商品VRP问题详解》 在物流配送、资源调度等领域,车辆路径规划(Vehicle Routing Problem, VRP)问题是一个经典的优化问题,它涉及到如何有效地安排车辆从一个或多个...

    pecl-5.2.5-Win32+php-5.2.13-Win32.zip

    "pecl-5.2.5-Win32.zip"包含的是适用于PHP 5.2.5的PECL扩展,这些扩展可以增加PHP对特定数据库的支持(如MySQLi、PDO等)、加密算法(如mcrypt)、图像处理库(如GD)以及其他许多实用功能。在Windows环境中,安装...

    python3.12对应的dlib-19.24.99-cp312-cp312-win-amd64

    1. **机器学习算法**:Dlib包含了各种机器学习算法,如支持向量机(SVM)、随机森林、神经网络等,为开发者提供了构建复杂模型的工具。 2. **计算机视觉**:Dlib在计算机视觉领域有着广泛的应用,如人脸识别、物体...

Global site tag (gtag.js) - Google Analytics