第七章 Win32汇编语言程序设计
Windows系统具有风格一致的华丽图形用户界面,丰富的
API函数,设备无关性、多任务等特点而广泛流行。
Win32汇编的功能:
?支持汇编语言程序调用 32位 Windows API函数 的功能
?支持类似 C语言的 高级语法和运算符
7.1 Win32汇编语言程序设计基础
在 Win32环境下,应用程序可以寻址 4GB空间。
用 Win32汇编语言可以容易地写出 Windows窗口应用程序。
在 Win32汇编环境下编写 Windows应用程序,可以充分利
用 Windows的高级特性,开发性能更高的应用软件和动态链
接库,而且可以从深层次理解 Windows运行机制和 Windows应
用程序的设计思路及方法。
next
EAX
EBX
ECX
EDX
数据寄存器
FLAG
AH
BH
CH
DH
AL
BL
CL
DL
SP
BP
SI
DI
IP
CS
DS
SS
ES
代码段寄存器
数据段寄存器
堆栈段寄存器
附加段寄存器(并新增 FS和 GS)
ESP堆栈指针寄存器
EBP基址指针寄存器
ESI 源变址寄存器
EDI 目的变址寄存器
EIP 指令指针寄存器
EFLAG 程序状态字寄存器
31 15 0
16 0
31 15 0
31 15 0
32位处理器寄存器结构:
返回
一个完整的 Win32汇编语言源程序结构如下所示:
.386 ;指定处理器指令集
.model flat,stdcall ;模式定义
option casemap:none ;指定汇编选项
<若干条 include 语句 > ;包含 API函数和动态链接库头文件
.stack [堆栈段大小 ] ;定义堆栈段
.data ;数据段 ( 定义初始化变量 )
<初始化变量定义 >
.data? ;数据段 ( 定义未初始化变量 )
<未初始化的变量定义 >
.const ;定义常量段
<常量定义 >
.code ;定义代码段
<开始标号 >
<若干语句 >
end 开始标号 ;源程序结束
例 7-1 写一个经典的 Win32 Hello程序 。 一个最简单的 Win32汇
编语言源程序例子, 说明 Win32汇编语言源程序的框架结构 。
.386 ;指定处理器指令集
.model flat,stdcall ;模式定义
option casemap,none ;指定汇编选项,区分大小写
include windows.inc ;包含 头文件和动态连接库
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.stack 100
.data
sztitle db ’ example of hello’,0
szgreet db ’你好 ! Win32世界 ! ’,0
.code
start, invoke MessageBox,NULL,addr szgreet,addr sztitle,\
MB_ICONINFORMATION or MB_OK
invoke ExitProcess,NULL
end start next
.model flat
定义了,model flat 平展 模式后, MASM将自动产生下面
的语句, 指定各段寄存器与段的关系:
ASSUME cs:flat,ds:flat,ss:flat,es:falt,fs:error,gs:error
Win32环境汇编语言编程接口就建立在 Win32 API基础上 。
Win32 API的核心是 3个 动态链接库 ( dll),
( 1) kernel32.dll
提供系统服务功能, 包括内存管理, 任务管理和动态链接等 。
( 2) user32.dll
提供用户接口服务功能, 包括创建窗口和传递消息等 。
( 3) gdi32.dll
提供图形设备接口, 实现文本及图形的显示操作 。 返回
源程序结构中的分段不再是 DOS汇编中的段定义概念, 而
是逐段连续分配各段地址空间, 上一段结束就是下一段的开
始 。
invoke 函数名 [,参数 1] [,参数 2]? ?
invoke MessageBox,NULL,addr szgreet,addr sztilte,MB_OK
上述调用在汇编语言程序中汇编为如下指令:
push MB_OK
push sztitle
push szgreet
push NULL
call MessageBox
MessageBox( )的原形声明如下:
int MessageBox(
HWND hwnd,//父窗口句柄
LPCTSTR lpText,//将显示在消息框中的字符串
LPCTSTR lpCaption //消息对话框的标题
UINT uType //消息对话框的风格 );
返回
invoke ExitProcess,NULL
void ExitProcess(
UINT uExitCode // exit code for all threads
) ;
返回
7.2 Win32的基本语法 ( 以下章节暂为教案 )
7.2.1 标号和变量
( 1) 标号
Win32汇编将标号的作用域局限于子程序范围内 。
(2) 变量
全局变量和局部变量, 变量的类型
获取变量的地址,获取全局变量和局部变量地址的操
作方法不同 。
7.2.2 子程序设计
( 1) 子程序的定义和说明
Win32汇编中的子程序都采用堆栈来传递参数, 参数的
存放位置, 顺序有一定的规则, 为 invoke伪指令进行参数
的语法检查和子程序调用提供了有利条件 。
( 2) 参数传递和堆栈平衡
Win32中子程序的语言类型约定是 StdCall,堆栈平衡操
作由子程序完成 。
7.2.3 高级语法
MASM 6.0以上的版本新引入了一系列实现高级语法的伪指
令, 其语句形式和功能与常见的高级语言类似, 使得汇编语
言程序的可读性和编程方便性提高到了高级语言的水平 。
( 1) 运算符与条件表达式
( 2) 分支语句
( 3) 循环语句
7.2.4 建立 Win32汇编的编程环境
MASM 6.10以上版本支持 Win32汇编。下面介绍两种形式
的常用编程环境:命令行编程环境或集成开发环境( IDE
Integrated Develop Envirroment)。
( 1)命令行编程环境
( 2)集成开发环境 next
.data
szmess db ‘n!=0 ',0
sztitle db 'WHILE examples',0
n dd 3
result dd 0
.code
start,mov ecx,1
mov eax,1
.while ecx<=n ;WHILE循环
mul ecx
inc ecx
add result,eax
.endw
mov eax,result
mov dl,al
add szmess+9,dl
invoke MessageBox,NULL,addr szmess,addr sztitle,B_OK
invoke ExitProcess,0
end start
例 7-2,用高级语法语句 WHILE循环完成计算, 1!+2!+3!=9
返回
迄今为止, MASM32软件包的最高版是 MASM32V8,可以
在发布者的主页 ( http://www.movsd.com) 上下载, 得到一个
压缩文件 masm32v8.zip, 解 压 后 的 文 件 是 install.exe, 在
Windows环境下运行该安装程序可进行软件包的安装 。
7.3 Win32窗口程序设计简介
Windows是多任务操作系统, 可以同时运行多个程序 。 系统
负责为每个程序分配和管理一块屏幕区域 ( 窗口 ) 供各程序专
用, 并且还有华丽的三维视觉外观和各种灵活的打开, 关闭,
移动及拖放等操作 。
7.3.1 Win32窗口程序示例
例 6-5是一个基本的 Win32窗口程序, 示范了窗口程序的基
本结构和处理消息的操作 。
该程序显示了一个带水平滚动条和垂直滚动条的窗口, 窗口
中创建了一个按钮, 窗口的客户区具有处理鼠标双击操作的功
能, 单击按钮或在窗口中任意处双击鼠标都将关闭窗口 。
一个基本的 Win32窗口示例:
7.3.2 窗口程序的运行过程
用户的所有操作(按下键盘、移动鼠标及拖拽窗口等)
都以消息的形式记录下来,由系统进行消息管理,最终在
API函数的支持下交给应用程序中的 窗口过程 处理。
6.3.3 窗口程序的主要代码分析
( 1)模块和句柄 ( 2)注册窗口类
( 3)建立窗口 ( 4)消息循环
( 5)窗口过程
Win32窗口过
程运行示意图
7.4 汇编语言与 VC++的混合编程
在实际应用问题中,编写汇编语言子程序或在高级语言中
嵌入汇编指令,以解决如下问题:
( 1)计算速度或代码长度的优化问题
( 2)为不兼容的代码提供接口
( 3)直接在高级语言中支持系统资源的访问和硬件控制
本节以 Windows下的 Visual C++ 6.0为例,介绍 32位编程环
境下汇编语言与 VC++语言的混合编程方法。
7.4.1 嵌入式汇编语言指令及编程方法
( 1) 嵌入式汇编语言指令的三种格式
① _ _asm指令块,_ _asm{ 汇编指令序列 }
② 单条 _ _asm指令
③一行多条 _ _asm指令,每条指令之间以空格分隔开
( 2) 使用嵌入式汇编语言的函数
嵌入式汇编也可以用于编写函数,其参数传递方法很简单,
并且不用单独汇编,因此使用方便。
例 1 用嵌入式汇编语言写一个阶乘函数。
例 2 基于上例,用 return语句返回 fac函数的出口参数。
7.4.2 VC++调用汇编语言子程序的方法
在 C/C++语言中可以调用汇编语言子程序, 其入口参数和
出口参数主要通过堆栈来传递 。
( 1) 调用规范与参数传递方法
( 2) 调用汇编语言子程序的方法举例
在模块调用方式下, 以一个 C++语言程序调用汇编语言子
程序为例, 说明汇编语言子程序的编写方法和几种参数传递
方式 。
( 3) 混合编程的上机调试方法
本章要求:
( 1)了解 Win32汇编语言程序的基本结构和两种编
程环境;
( 2)掌握 Win32汇编语言 基本语法 和 高级语法 ;
( 3)深入理解 Windows消息传递机制, 熟悉 API函
数,熟悉窗口程序的结构,掌握窗口程序的编
程方法;
( 4)灵活应用汇编语言和高级语言的 混合编程 方法,
掌握解决实际应用中关键技术问题的一种有效
方法。
小 结
认真复习,融会贯通
继续拓展新知识
Windows系统具有风格一致的华丽图形用户界面,丰富的
API函数,设备无关性、多任务等特点而广泛流行。
Win32汇编的功能:
?支持汇编语言程序调用 32位 Windows API函数 的功能
?支持类似 C语言的 高级语法和运算符
7.1 Win32汇编语言程序设计基础
在 Win32环境下,应用程序可以寻址 4GB空间。
用 Win32汇编语言可以容易地写出 Windows窗口应用程序。
在 Win32汇编环境下编写 Windows应用程序,可以充分利
用 Windows的高级特性,开发性能更高的应用软件和动态链
接库,而且可以从深层次理解 Windows运行机制和 Windows应
用程序的设计思路及方法。
next
EAX
EBX
ECX
EDX
数据寄存器
FLAG
AH
BH
CH
DH
AL
BL
CL
DL
SP
BP
SI
DI
IP
CS
DS
SS
ES
代码段寄存器
数据段寄存器
堆栈段寄存器
附加段寄存器(并新增 FS和 GS)
ESP堆栈指针寄存器
EBP基址指针寄存器
ESI 源变址寄存器
EDI 目的变址寄存器
EIP 指令指针寄存器
EFLAG 程序状态字寄存器
31 15 0
16 0
31 15 0
31 15 0
32位处理器寄存器结构:
返回
一个完整的 Win32汇编语言源程序结构如下所示:
.386 ;指定处理器指令集
.model flat,stdcall ;模式定义
option casemap:none ;指定汇编选项
<若干条 include 语句 > ;包含 API函数和动态链接库头文件
.stack [堆栈段大小 ] ;定义堆栈段
.data ;数据段 ( 定义初始化变量 )
<初始化变量定义 >
.data? ;数据段 ( 定义未初始化变量 )
<未初始化的变量定义 >
.const ;定义常量段
<常量定义 >
.code ;定义代码段
<开始标号 >
<若干语句 >
end 开始标号 ;源程序结束
例 7-1 写一个经典的 Win32 Hello程序 。 一个最简单的 Win32汇
编语言源程序例子, 说明 Win32汇编语言源程序的框架结构 。
.386 ;指定处理器指令集
.model flat,stdcall ;模式定义
option casemap,none ;指定汇编选项,区分大小写
include windows.inc ;包含 头文件和动态连接库
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.stack 100
.data
sztitle db ’ example of hello’,0
szgreet db ’你好 ! Win32世界 ! ’,0
.code
start, invoke MessageBox,NULL,addr szgreet,addr sztitle,\
MB_ICONINFORMATION or MB_OK
invoke ExitProcess,NULL
end start next
.model flat
定义了,model flat 平展 模式后, MASM将自动产生下面
的语句, 指定各段寄存器与段的关系:
ASSUME cs:flat,ds:flat,ss:flat,es:falt,fs:error,gs:error
Win32环境汇编语言编程接口就建立在 Win32 API基础上 。
Win32 API的核心是 3个 动态链接库 ( dll),
( 1) kernel32.dll
提供系统服务功能, 包括内存管理, 任务管理和动态链接等 。
( 2) user32.dll
提供用户接口服务功能, 包括创建窗口和传递消息等 。
( 3) gdi32.dll
提供图形设备接口, 实现文本及图形的显示操作 。 返回
源程序结构中的分段不再是 DOS汇编中的段定义概念, 而
是逐段连续分配各段地址空间, 上一段结束就是下一段的开
始 。
invoke 函数名 [,参数 1] [,参数 2]? ?
invoke MessageBox,NULL,addr szgreet,addr sztilte,MB_OK
上述调用在汇编语言程序中汇编为如下指令:
push MB_OK
push sztitle
push szgreet
push NULL
call MessageBox
MessageBox( )的原形声明如下:
int MessageBox(
HWND hwnd,//父窗口句柄
LPCTSTR lpText,//将显示在消息框中的字符串
LPCTSTR lpCaption //消息对话框的标题
UINT uType //消息对话框的风格 );
返回
invoke ExitProcess,NULL
void ExitProcess(
UINT uExitCode // exit code for all threads
) ;
返回
7.2 Win32的基本语法 ( 以下章节暂为教案 )
7.2.1 标号和变量
( 1) 标号
Win32汇编将标号的作用域局限于子程序范围内 。
(2) 变量
全局变量和局部变量, 变量的类型
获取变量的地址,获取全局变量和局部变量地址的操
作方法不同 。
7.2.2 子程序设计
( 1) 子程序的定义和说明
Win32汇编中的子程序都采用堆栈来传递参数, 参数的
存放位置, 顺序有一定的规则, 为 invoke伪指令进行参数
的语法检查和子程序调用提供了有利条件 。
( 2) 参数传递和堆栈平衡
Win32中子程序的语言类型约定是 StdCall,堆栈平衡操
作由子程序完成 。
7.2.3 高级语法
MASM 6.0以上的版本新引入了一系列实现高级语法的伪指
令, 其语句形式和功能与常见的高级语言类似, 使得汇编语
言程序的可读性和编程方便性提高到了高级语言的水平 。
( 1) 运算符与条件表达式
( 2) 分支语句
( 3) 循环语句
7.2.4 建立 Win32汇编的编程环境
MASM 6.10以上版本支持 Win32汇编。下面介绍两种形式
的常用编程环境:命令行编程环境或集成开发环境( IDE
Integrated Develop Envirroment)。
( 1)命令行编程环境
( 2)集成开发环境 next
.data
szmess db ‘n!=0 ',0
sztitle db 'WHILE examples',0
n dd 3
result dd 0
.code
start,mov ecx,1
mov eax,1
.while ecx<=n ;WHILE循环
mul ecx
inc ecx
add result,eax
.endw
mov eax,result
mov dl,al
add szmess+9,dl
invoke MessageBox,NULL,addr szmess,addr sztitle,B_OK
invoke ExitProcess,0
end start
例 7-2,用高级语法语句 WHILE循环完成计算, 1!+2!+3!=9
返回
迄今为止, MASM32软件包的最高版是 MASM32V8,可以
在发布者的主页 ( http://www.movsd.com) 上下载, 得到一个
压缩文件 masm32v8.zip, 解 压 后 的 文 件 是 install.exe, 在
Windows环境下运行该安装程序可进行软件包的安装 。
7.3 Win32窗口程序设计简介
Windows是多任务操作系统, 可以同时运行多个程序 。 系统
负责为每个程序分配和管理一块屏幕区域 ( 窗口 ) 供各程序专
用, 并且还有华丽的三维视觉外观和各种灵活的打开, 关闭,
移动及拖放等操作 。
7.3.1 Win32窗口程序示例
例 6-5是一个基本的 Win32窗口程序, 示范了窗口程序的基
本结构和处理消息的操作 。
该程序显示了一个带水平滚动条和垂直滚动条的窗口, 窗口
中创建了一个按钮, 窗口的客户区具有处理鼠标双击操作的功
能, 单击按钮或在窗口中任意处双击鼠标都将关闭窗口 。
一个基本的 Win32窗口示例:
7.3.2 窗口程序的运行过程
用户的所有操作(按下键盘、移动鼠标及拖拽窗口等)
都以消息的形式记录下来,由系统进行消息管理,最终在
API函数的支持下交给应用程序中的 窗口过程 处理。
6.3.3 窗口程序的主要代码分析
( 1)模块和句柄 ( 2)注册窗口类
( 3)建立窗口 ( 4)消息循环
( 5)窗口过程
Win32窗口过
程运行示意图
7.4 汇编语言与 VC++的混合编程
在实际应用问题中,编写汇编语言子程序或在高级语言中
嵌入汇编指令,以解决如下问题:
( 1)计算速度或代码长度的优化问题
( 2)为不兼容的代码提供接口
( 3)直接在高级语言中支持系统资源的访问和硬件控制
本节以 Windows下的 Visual C++ 6.0为例,介绍 32位编程环
境下汇编语言与 VC++语言的混合编程方法。
7.4.1 嵌入式汇编语言指令及编程方法
( 1) 嵌入式汇编语言指令的三种格式
① _ _asm指令块,_ _asm{ 汇编指令序列 }
② 单条 _ _asm指令
③一行多条 _ _asm指令,每条指令之间以空格分隔开
( 2) 使用嵌入式汇编语言的函数
嵌入式汇编也可以用于编写函数,其参数传递方法很简单,
并且不用单独汇编,因此使用方便。
例 1 用嵌入式汇编语言写一个阶乘函数。
例 2 基于上例,用 return语句返回 fac函数的出口参数。
7.4.2 VC++调用汇编语言子程序的方法
在 C/C++语言中可以调用汇编语言子程序, 其入口参数和
出口参数主要通过堆栈来传递 。
( 1) 调用规范与参数传递方法
( 2) 调用汇编语言子程序的方法举例
在模块调用方式下, 以一个 C++语言程序调用汇编语言子
程序为例, 说明汇编语言子程序的编写方法和几种参数传递
方式 。
( 3) 混合编程的上机调试方法
本章要求:
( 1)了解 Win32汇编语言程序的基本结构和两种编
程环境;
( 2)掌握 Win32汇编语言 基本语法 和 高级语法 ;
( 3)深入理解 Windows消息传递机制, 熟悉 API函
数,熟悉窗口程序的结构,掌握窗口程序的编
程方法;
( 4)灵活应用汇编语言和高级语言的 混合编程 方法,
掌握解决实际应用中关键技术问题的一种有效
方法。
小 结
认真复习,融会贯通
继续拓展新知识