文章目录
- 输入/输出指令和数据的传送方式
- 输入/输出指令
- 输入指令IN
- 输出指令OUT
- 串输入指令INS
- 串输出指令OUTS
- 数据的传送方式
- 无条件传送
- 查询传送
- 直接存储器
- 中断传送
- 中断与异常
- 中断的概念
- 不可屏蔽中断 NMI
- 可屏蔽中断 INTR
- 除法出错
- 溢出
- 调试异常(单步)
- 软中断(INT N)
- 中断矢量表
- 软中断及相关代码
- 软中断指令
- 中断返回指令
- 中断处理程序的设计
- 新增一个中断处理程序的步骤
- 修改已有中断处理程序以拓展其功能
- 外设中断注意事项
- 软中断注意事项
- 浮点运算
- FPU中的寄存器
- 浮点数据寄存区和标记寄存器
- 状态寄存器
- 控制寄存器
- 浮点指令与程序设计
- 向FPU中装入数据的指令
- 从FPU中取出数据的指令
- 交换指令
- 基本算术指令
- 超越函数指令
- 控制和常数指令
- WIN32编程
- 基础
- 32位编程环境
- 库和头文件
- 宏汇编语言对WIN32编程的支持
- 段的简化定义
- 存储模型说明MODEL
- 定义代码段CODE
- 定义数据段DATA?
- 其它伪指令
- 原型说明与函数调用
- 原型说明PROTO
- 完整的函数定义PROC
- 函数调用INVOKE
- 局部变量伪指令LOCAL
- 结构
- WIN32程序的结构
- Windows API函数简介
- 主程序中使用的API函数
- 获取应用程序模块的句柄
- 获得指向当前命令行缓冲区的指针
- 退出程序
- 窗口主程序中使用的API函数
- 注册窗口
- 创建窗口
- 载入相关资源
- 载入一个图标
- 载入一个菜单
- 设定菜单
- 载入光标
- 获得用户去窗口大小
- 初始化公用控件
- 消息循环
- 获取消息
- 转换键盘消息
- 分发消息
- 窗口过程中使用的API函数
- 消息处理函数
- 显示消息框
- 显示字符串
- 发送消息
- 发送退出消息
- 消息的缺省出来函数
- 文件操作
- 打开和创建
- 关闭
- 读
- 写
- 获取文件长度
输入/输出指令和数据的传送方式
- 在80Xx86的PC机中,除了内存空间,还有IO空间
- IO空间用于访问外设中的寄存器
- IO空间只能由IO指令访问
- 编址方式与内存相同,地址范围为0~0FFFFH,共64K
- 寄存器称为端口,分为状态寄存器、控制寄存器、数据寄存器
- 状态寄存器:描述当前设备所处的工作状态
- 控制寄存器:存放控制设备当前工作方式所需的信息
- 数据寄存器:暂存与CPU交换的数据
输入/输出指令
- I/O空间的访问不存在分段的问题
- 保护方式下,存在访问保护,CPU遇到IO指令时,检查特权级和IO允许图
输入指令IN
IN OPD,OPS
- 从指定的端口OPS中读取数据,送入累加器OPD中
- 外设寄存器地址为0-255时,可用立即数表示,大于255时,只能DX表示
- OPD只能是累加器
输出指令OUT
OUT OPD,OPS
- 将累加器OPS中的内容,送到外设地址OPD之中
- 外设寄存器地址为0-255时,可用立即数表示,大于255时,只能DX表示
- OPS只能是累加器
串输入指令INS
INS OPD,DX
INSB — 输入字节串
INSW — 输入字串
INSD — 输入双字串
- ( [DX] ) -> ES : [ DI/EDI ]
- DF=0时增量,DF=1时减量
- 如果与REP前缀连用,则INS可以传输信息块到连续的存储空间OPD
串输出指令OUTS
OUTS DX,OPD
OUTB — 输出字节串
OUTW — 输出字串
OUTD — 输出双字串
- DS : [ SI/ESI ] -> ( [DX] )
- DF=0时增量,DF=1时减量
- 如果与REP前缀连用,则可以将内存中连续内容送到输出端口
数据的传送方式
无条件传送
- 在传送数据时,不考虑外设的工作状态
- 在输入数据时,总认为外设已经将数据准备就绪
- 该方式要求外设工作速度与CPU同步
查询传送
- CPU与外设不同步
- 输入前,查询数据是否就绪
- 输出前,查询外设是否就绪
- 查询会占用大量的CPU时间
直接存储器
- DMA(direct memory access)
- 利用DMA控制器管理数据IO,适用于高速IO设备
中断传送
外设就绪后,发送中断请求给CPU
中断与异常
中断的概念
- CPU打断当前执行程序,转而为临时的事件服务,事后自动恢复
- 实现这种功能的软硬件装置,称为中断系统
- 处理事件的程序,称为中断处理程序
- 引起中断的事件称为中断源
中断分为:
- 外部中断
- 不可屏蔽中断 NMI
- 可屏蔽中断 INTR
- 内部中断
- CPU检测:除法错误、单步中断、协处理器段超越等
- 程序检测:软中断,包括INTO,INT N 和 BOUND 等
一般情况下,把外部中断称为中断,内部中断称为异常
不可屏蔽中断 NMI
由硬件故障引起,如果不及时响应,机器就无法正常运转下去
可屏蔽中断 INTR
可屏蔽中断由各种外设的中断请求产生,CPU的IF标志,决定是否响应中断
除法出错
执行除法指令时,如果除数是0,或者商超出了寄存器所能表示的最大范围,产生一个中断号为0的内部异常
溢出
溢出标志 OF=1时,执行指令INTO将会产生中断号为4的异常
调试异常(单步)
- 指令地址断点异常
- 数据地址断点异常
- 一般检查异常
- 单步异常(TF=1)
- 任务转换断点异常
软中断(INT N)
中断矢量表
- 中断矢量表是中断号与对应的中断处理程序之间的连接表
- 中断矢量表连续存放了256个表项,每个表项中存放了中断处理函数入口的段和偏移地址
- 实方式下,中断矢量表仅存放16位的段值和16位的偏移值,每个表项占用4B
- 保护方式下,中断矢量表称为中断描述符表(IDT),每个表项存放入口信息、类别、权限等, 占用8B
中断描述符分为:
- 任务门:执行中断处理程序时将发生任务转移
- 中断门:主要用于处理外部中断,响应中断时自动将TF和IF置零
- 陷阱门:主要用于处理异常,响应中断时TF置零
软中断及相关代码
软中断指令
INT n
其中n是中断号,取值范围0-255
- 实方式:
- FLAGS压栈,IF、TF置零
- CS压栈,计算新的CS并赋值
- IP压栈,得到新的IP赋值
- 32位段:
- EFLAGS压栈,IF、TF置零
- CS拓展为32位压栈,从门或者TSS描述符指向的数据区分离出段选择符,计算得到新的CS赋值
- EIP压栈,从门或者TSS描述符指向的数据区分离出偏移值,计算得到新的EIP赋值
中断返回指令
IRET
- IP/EIP出栈,CS出栈,FLAGS/EFLAGS出栈
中断处理程序的设计
主要包括:为尚未分配功能的中断号设计一个中断处理程序,或修改已有的中断处理程序以扩充其功能
新增一个中断处理程序的步骤
- 根据新增加的功能需求,编制中断处理程序,远过程,IRET返回
- 查看中断矢量表,找空闲中断号m
- 将新编制的中断处理程序装入内存,其入口地址送到中断矢量表
修改已有中断处理程序以拓展其功能
- 根据需求编制程序段
- 将程序装入内存,将入口地址复制到程序段中,用新的入口地址取代中断矢量表中已有的入口地址
外设中断注意事项
- 必须保护现场
- 及时开中断以便CPU能响应更高级的中断请求
- 通过选用高效的指令和编制短小的程序来尽快完成中断处理的任务
- 恢复现场
- 通知中断控制器中断已结束
- 利用IRET指令实现中断返回
软中断注意事项
- 考虑切换堆栈
- 保护现场
- 在实方式下应该及时开中断,以便CPU能响应外设的中断请求
- 按照一般速度要求完成中断处理
- 恢复现场
- 堆栈切换还原
- 一般用IRET指令实现中断返回
浮点运算
FPU中的寄存器
- 8个独立寻址、按寄存器栈组织的80位浮点数据寄存器
- 3个16位寄存器(状态字、控制字和标记字寄存器)
- 2个出错指针(一个指向最后一条指令,另一个指向最后一个操作数)
- 1个操作码,是最后一条非控制的FPU指令操作吗,由11位寄存器存放
浮点数据寄存区和标记寄存器
- 8个浮点数据寄存器编号为FPR0-FPR7
- 由8个浮点数据寄存器组成首尾相接的堆栈
- 汇编中使用的浮点寄存器的助记符是ST(0) - ST(7),其中0是栈顶,由状态寄存器的TOP字段指明
- 对应每个FPR寄存器,都有一个2位的标记域,含义如下
- 00 对应的数据寄存器中存有有效的数据
- 01 对应的数据寄存器中数据为0
- 10 对应的数据寄存器中数据是特殊数据(NaN,∞等)
- 11 对应的数据寄存器没有数据
状态寄存器
状态寄存器表明FPU当前的各种操作状态以及每条浮点指令执行后所得结果的特征,其作用与CPU中的标志寄存器相当
- 状态寄存器的低6位,反应6种错误,置位后的错误标志必须指令清除
- C0-C3是条件标志位,是根据FPU运算后所得结果自动设置的
控制寄存器
控制寄存器用于控制FPU的异常屏蔽、精度和舍入操作
浮点指令与程序设计
- FPU具有自己的指令系统
- 浮点指令属于ESC(转义)指令
- 其前5位的操作码都是11011B,它们的助记符都是F开头
- 操作数不能是立即数
向FPU中装入数据的指令
FLD OPS ;将主存或ST中的浮点数压入栈顶
FILD OPS ;将主存中的整数压入栈顶
FBLD OPS ;将主存中的BCD码数压入栈顶
从FPU中取出数据的指令
FST OPD ;将栈顶的数据存放到ST(I)或按变量的浮点格式存放到主存中
FIST OPD ;将栈顶的数据按照整数格式存放到主存中
以上两条指令不改变FPU内浮点数据寄存器栈的状态
FSTP OPD ;将栈顶数据,按浮点格式存放到ST(I)或主存中,然后出栈
FISTP OPD ;将栈顶数据,按整数格式,存放主存,然后出栈
FBSTP OPD ;将栈顶数据,按BCD码格式存入主存,然后出栈
交换指令
FXCH ;ST0和ST1内容交换
FXCH ST(i) ;ST0和STi内容交换
基本算术指令
FADD ST(i),ST(j) ;STi + STj -> STi,i和j至少有一个0,至少有一个是ST0
FADD OPS ;ST0 + OPS -> ST0
FIADD OPS ;ST0 + OPS -> ST0
FSUB ST(i),ST(j) ;STi + STj -> STi,其中至少一个0
FSUB OPS ;ST0 - OPS -> ST0
FISUB OPS ;ST0 - OPS -> ST0
FMUL ST(i),ST(j) ;STi * STj -> STi,其中i和j至少有一个为0
FMUL OPS ;ST0 * OPS -> ST0
FIMUL OPS ;ST0 * OPS -> ST0
FDIV ST(i),ST(j) ;STi / STj -> STi
FDIV OPS ;ST0 / OPS -> ST0
FIDIV OPS ;ST0 / OPS -> ST0
FSQRT ;计算ST0的平方根 -> ST0
超越函数指令
FSIN
FCOS
控制和常数指令
FINIT:初始化浮点单元
FLDPI:把常数π送到FPU堆栈上
WAIT:使处理器检查数值异常
WIN32编程
基于Windows运行环境的32位段程序简称为WIN32程序
基础
32位编程环境
- 一个完整的编程环境应该包括 编译工具、汇编程序、连接程序、调试程序
- windows提供的系统功能不再是软中断,而是子程序库的形式,因此必须先引入,增加外部过程及相关外部变量的说明
- 按照功能分类,函数代码放在不同的动态连接库文件中,函数代码的位置信息存放在不同的引入库文件中,函数的原型说明信息存放在不同的头文件中
- 在win32编程中,将常用的、组成显示界面的信息称为资源,如菜单、对话框、字符串、图标和位图等
库和头文件
- 由于提供了大佬的动态连接库,引入库和头文件,因此编程时只需要指明引入信息即可
- KERNEL32.LIB:负责处理内存管理和进程调度,对应函数原型说明信息存放在头文件KERNEL32.INC中
- USER32.LIB:负责控制用户界面,对应函数原型说明信息存放在头文件USER32.INC中
- GDI32.LIB:负责图形方面的操作,对应的函数原型说明信息存放在头文件GDI32.INC中
- 连接程序需要引入库的信息,方法有两种,一是程序中INCLUDELIB说明,二是连接时,指定库文件路径
- WINDOWS.INC将API中常用的常量和结构体定义集中存放于此
宏汇编语言对WIN32编程的支持
段的简化定义
如果要在程序中使用段名,可以通过预定义符来指定,如:@DATA、@CODE
存储模型说明MODEL
简化的段定义伪指令均以符号点 .
引导
.MODEL 存储模型,语言类型,系统类型,堆栈选项
- 用于指定程序中各段的属性、程序运行的环境、调用规则等
- 存储模型:指定内存管理模式
- 语言类型:指定了函数命名、调用和返回的方法
- 系统类型:目前只有OS_DOS选项
- 堆栈选项:包括NEARSTACK和FARSTACK
- 该指令必须放在源文件中所有其它段定义之前,且只能使用一次
定义代码段CODE
.CODE 段名
说明一个代码段的开始,同时也表示上一个段的结束
定义数据段DATA?
.DATA 或者 .DATA?
- 说明一个数据段的开始,同时也表示上一个段的结束
- 当采用.DATA时,段内的变量初始化,占用执行文件的存储空间,其段名指定为_DATA
- 当采用.DATA?时,段内变量未初始化,也不占用存储空间,其段名指定为_BSS
其它伪指令
.STACK 堆栈字节数
.CONST 常数段伪指令
.STARTUP 程序开始伪指令
原型说明与函数调用
- 在子程序参数较多,或者与高级语言混合编程时,使得参数传递变得复杂,容易出错
- 为解决此问题,提供了PROTO和INVOKE伪指令,使子程序的说明类似于高级语言的原型说明
原型说明PROTO
函数名 PROTO 函数类型,语言类型,参数名:参数类型…
- 说明本模块中要调用的函数
- 函数类型:指明了子程序的类型,可以是NEAR,FAR,NEAR16,NEAR32,FAR16,FAR32
- 语言类型:指明参数传递的方式采用哪种语言的规定
- PROTO的功能类似于EXTERN,但表达能力更强
完整的函数定义PROC
函数名 PROC 函数类型,语言类型,USES寄存器表,参数名:类别
- 定义一个新的函数,函数体紧跟其后
- 与PROTO格式相似,USES后面的寄存器是需要入栈保护的
- PROTO和PROC都没有说明返回参数,如果有返回值,默认放在累加寄存器中
- 如果有多个返回参数,则通过指针存放到调用者的程序空间
函数调用INVOKE
INVOKE 函数名 参数…
- 调用由完整的函数定义PROC定义的函数
- 参数可以是各种表达式
- ADDR BUF 等价于OFFSET BUF,ADDR经验处理局部变量,而OFFSET不能
局部变量伪指令LOCAL
在函数定义的PROC之后,可以用LOCAL指令说明仅在本函数内使用的局部变量
LOCAL 变量名 数量:类型
结构
结构名 STRUCT
数据定义语句序列
结构名 ENDS
- 结构是用户自定义的复合数据类型,它将各种不同类型的数据组织到一个数据结构中,以方便处理复杂的数据项
- 在描述结构型数据或使用结构型变量之前,需要先对结构进行说明
- STRUCT和ENDS要配对使用
- 数据定义语句序列是一组变量的定义语句
- 结构说明只是定义了一个框架,并未分配主存空间,只有在利用该类型为自己的程序定义一个结构变量时才进行存储分配
- 结构变量一般放在数据段中,而结构说明应该放在结构变量定义之前,不属于任何段
定义结构变量的一般格式:
变量名 结构名 <字符赋值表>
- 定义结构变量时,不能对含有多个项目的字段重新赋值,要修改必须通过指令
- 如果要存取某个结构变量,采用结构变量名.结构字段名的形式,如:MOV EAX,C2.CID
WIN32程序的结构
windows下的程序框架相当复杂,为了方便程序员,Windows开发包的文档中规定了各种Windows程序(核心驱动程序、动态链接库、窗口应用程序等)的标准框架
基于窗口的应用程序可以简单地划分为4个部分
-
主程序:OS首先执行主程序,获得本程序有关的基本信息后,再调用窗口主程序
-
窗口主程序:创建指定窗口后,将该窗口收到的消息通过操作系统转发到窗口消息处理程序
-
窗口消息处理程序:判断收到的消息种类,决定调用用户处理程序中的哪些函数完成相应功能
-
用户处理程序:用户自己实现的程序
-
主程序:可以根据需求安排任何指令,但为了适应窗口程序的需要,必须完成规定的初始化工作,主要包括:获取本程序在主存中的地址(也称句柄),获取命令行参数的地址,调用窗口主程序等
-
句柄:是用来唯一标识某一个程序、窗口等的代号,一般是它们的地址,用户需要通过API获取句柄,然后才能通过句柄对所代表的内容进行操作(发送信息等)
-
用户处理程序:是完成用户实际需求的各种函数的集合,一般是用户按照需求,自行命名、编写的函数,完全可以按照子程序设计方法编写
-
窗口主程序:是一个调用了多个Windows API函数的函数体,一般命名为WinMain,它首先完成窗口的创建、程序所需资源的装载等操作,然后不断从操作系统中获取对所创建窗口进行操作的信息,并分发到窗口消息处理程序,它的原型说明为:
WinMain PROTO hInst :DWORD, ;应用程序的实例句柄
hPrevInst :DWORD, ;前一个实例句柄
lpCmdLine :DWORD, ;命令行指针,指向以0结束的命令行字符串
nCmdShow :DWORD ;指出如何显示窗口
实例:是指主存中实际存在的程序代码和数据,用于区别程序代码和数据的描述信息
消息:是指发给应用程序的各种命令,系统将这些命令转换成统一的格式,按照命令产生的时间顺序放在消息队列中,每个消息用MSG结构定义如下:
MSG STRUCT
hwnd DD ? //窗口句柄,指明消息属于哪个窗口
message DD ? //消息号,指明消息的种类
wParam DD ? //消息的附加信息
lParam DD ? //消息的附加信息
time DD ? //指明消息产生的时间
pt POINT <> //指明消息产生时,光标相对屏幕坐标的位置
- 窗口消息处理程序:主要功能是对接收到的消息进行判断,以便分类处理,一般命名为WndProc,原型说明如下:
WndProc PROTO hWin : DWORD //窗口句柄
uMsg : DWORD //消息号,指明消息的种类,是判断分支的依据
wParam:DWORD //该消息的附加信息,若是子消息号,则是嵌套分支判断的依据
lParam:DWORD //该消息的附加信息
为了简化分支程序的设计,高版本的汇编程序提供了多个条件控制流伪指令,还支持多个比较关系操作符,包括
相等 | 不等 | 大于 | 小于 | 大于等于 | 小于等于 | 逻辑非 | 逻辑与 | 逻辑或 |
---|---|---|---|---|---|---|---|---|
== | != | > | < | >= | <= | ! | && | || |
位测试 | 进位标志 | 符号标志 | 零标志 | 溢出标志 | 奇偶标志 |
---|---|---|---|---|---|
& | CARRY? | SIGN? | ZERO? | OVERFLOW? | PARITY |
这些操作符可以用于比较变量、寄存器和常数,还可以组合成复杂的条件表达式,在窗口消息处理函数中,常用IF伪指令
.IF 条件表达式
语句序列
.ELSEIF 条件表达式
语句序列
.ELSE
语句序列
.ENDIF
Windows API函数简介
主程序中使用的API函数
获取应用程序模块的句柄
GetModuleHandle PROTO lpModuleName:DWORD
输入参数lpModuleName是一个地址指针,指向一个正在系统中运行的程序的名字串,指针赋值为0时,标识获取调用此API程序的句柄,调用成功时,返回值为句柄,否则返回0
获得指向当前命令行缓冲区的指针
GetCommandLine PROTO
调用后返回一个指向当前程序的命令行字符串的地址指针
退出程序
ExitProcess PROTO uExitCode:DWORD
uExitCode标识退出码,正常退出为0,退出用户程序,返回操作系统
窗口主程序中使用的API函数
常用的有以下4类函数
注册窗口
该函数用于注册用户定义的窗口类,若创建的窗口是基于Windows预先定义的类,则不必注册
RegisterClassEx PROTO lpwex:DWORD
该函数的输入参数是指向一个按照WNDCLASSEX结构定义的指针,定义如下:
WNDCLASSEX STRUCT
cbSize DD ? //大小,字节数
style DD ? //窗口具有的风格,可以用OR
lpfnWndProc DD ? //窗口消息处理函数的指针
cbClsExtra DD ? //附加字节数
cbWndExtra DD ? //附加字节数
hInstance DD ? //窗口所属模块的实例句柄
hIcon DD ? //图标资源的句柄,为0时,使用缺省图标
hCursor DD ? //光标资源的句柄,为0时缺省
hbrBackground DD ? //背景色
lpszMenuName DD ? //在资源文件中描述菜单的资源名字符串的指针
lpszClassName DD ? //指向类名称的指针
hIconSm DD ? //与窗口类关联的小图标的句柄,为0时,将hIcon指定的图标转换为合适大小
WNDCLASSEX ENDS
结构变量初始化时,参数值选择范围较大的是窗口风格style和背景色hbrBackgroud
style的取值可以是以下值或者组合
CS_VREDRAW//如果窗口移动或调整大小后改变了用户区的高度,则重画整个窗口
CS_HREDRAW//如果窗口移动或调整大小后改变了用户区的宽度,则重画整个窗口
CS_DBLCLKS//当鼠标在该窗口内双击时,将双击消息发送到窗口消息处理函数
CS_OWNDC//该类的每个窗口都指定单独的设备上下文句柄
CS_CLASSDC//为用该类创建的所有窗口指定一个共享的设备上下文句柄
CS_PARENTDC//设置子窗口在父窗口中限制区域以提高性能
CS_NOCLOSE//在系统菜单中取消“关闭”功能
CS_SAVEBITS//在几个窗口间切换时,用位图的形式保存、恢复本窗口中被覆盖的内容
CS_BYTEALIGNCLIENT//窗口的用户使用区在水平X方向的边界具有字节特性,以提高绘图性能
CS_BYTEALIGNWINDOW//窗口在水平X方向的边界具有字节特性,以提高窗口移动和缩放性能
CS_GLOBALCLASS//强制程序只使用注册窗口时的实例句柄hInstance来创建窗口
窗口背景色hbrBackgroud可以是以下定义中的一个值,但在给它赋值时,需要在以下基础上加1
COLOR_SCROLLBAR//滚动条的颜色类型
COLOR_BACKGROUND//背景的颜色类型
COLOR_ACTIVECAPTION//活动标题栏的颜色类型
COLOR_INACTIVECAPTION//未激活标题栏的颜色类型
COLOR_MENU//菜单栏的颜色类型
COLOR_WINDOW//窗口的颜色类型
COLOR_WINDOWFRAME//窗口框架的颜色类型
COLOR_MENUTEXT//菜单文字的颜色类型
COLOR_WINDOWTEXT//窗口文字的颜色类型
COLOR_CAPTIONTEXT//标题文字的颜色类型
COLOR_ACTIVEBORDER//活动边界的颜色类型
COLOR_INACTIVEBORDER//未激活边界的颜色类型
COLOR_APPWORKSPACE//程序工作区的颜色类型
COLOR_HIGHLIGHT//高亮的颜色类型
COLOR_HIGHLIGHTTEXT//高亮文字的颜色类型
COLOR_BTNFACE//按钮面的颜色类型
COLOR_BTNSHADOW//按钮阴影的颜色类型
COLOR_GRAYTEXT//灰文字的颜色类型
COLOR_BTNTEXT//按钮文字的颜色类型
创建窗口
CreateWindowEx PROTO
dwExStyle : DWORD //扩展的窗口风格,可为 0
lpClassName : DOWRD //指向已注册类的名字的指针
lpWindowName : DWORD//指向窗口名字的指针,该名字串会显示到窗口的标题栏上
dwStyle : DWORD//窗口的风格
x : DWORD//窗口左上角顶点的水平坐标值
y : DWORD //窗口左上角顶点的垂直坐标值
nWidth : DWORD//窗口宽度
nHight : DWORD//窗口高度
hWndParant : DWORD//父窗口或所属窗口的句柄,0 表示没有
hMenu : DWORD//附加菜单的句柄或子窗口的标识符,0 表示没有
hInstance : DWORD//产生该窗口的应用程序的实例句柄
lpParam : DWORD//指向欲传给窗口的结构体数据类型参数的指针
如果函数执行成功,则EAX中的返回值是所创建窗口的句柄,执行失败返回0,创建窗口时,参数dwExStyle和dwStyle是可以根据需要取值的,参数dwExStyle可以是以下的一个或组合
WS_EX_DLGMODALFRAME//指定具有双边界的窗口
WS_EX_NOPARENTNOTIFY//当子窗口被创建和取消时,子窗口不向父窗口发送WS_PARENTNOTIFY消息
WS_EX_TOPMOST//指定该窗口总放在最前面
WS_EX_ACCEPTFILES//指定用此方式创建的窗口接受拖放文件
WS_EX_TRANSPARENT//创建一个透明的窗口
WS_EX_CLIENTEDGE//指定窗口的边界具有凹陷效果
WS_EX_APPWINDOW//在任务条上显示本窗口的小窗口
参数dwStyle除了可以选用通用的预定值外,还可以选用将创建的窗口所使用的的类所定义的值,dwStyle可以是下列预定值的一种或组合
WS_OVERLAPPED//创建一个重叠式窗口(带有一个标题栏和边框)
WS_CHILD//创建一个子窗口
WS_VISIBLE//创建一个初始时可见的窗口
WS_CAPTION//窗口有一个标题栏
WS_VSCROLL//窗口具有一个垂直滚动条
WS_HSCROLL//窗口具有一个水平滚动条
WS_SYSMENU//在标题栏中具有系统菜单框的窗口(应同时指定WS_CAPTION)
WS_THICKFRAME//宽边框的窗口
WS_MINIMIZEBOX//窗口带有最小化按钮
WS_MAXIMIZEBOX//窗口带有最大化按钮
WS_OVERLAPPEDWINDOW//窗口具有WS_OVERLAPPED、WS_CAPTION、WS_SYSMENU、WS_THICKFRAME、WS_MINIMIZEBOX 、WS_MAXIMIZEBOX的风格(最常用的)
载入相关资源
在注册和创建窗口时,有些初始值需要通过API函数获得,有些需要API函数设定
载入一个图标
LoadIcon PROTO
hInstance : DWORD//应用程序实例句柄,当装入标准图标时,此参数为 0
lpIconName : DWORD//图标资源的名字或资源的标识符
如果函数执行成功,返回刚装入的图标的句柄,否则返回0
载入一个菜单
LoadMenu PROTO
hInstance : DWORD//应用程序实例句柄
lpMenuName : DWORD//菜单的名字或菜单资源的标识符
如果函数执行成功,返回刚装入的菜单资源的句柄,否则返回0
设定菜单
SetMenu PROTO
hWnd : DWORD//被赋予菜单的窗口的句柄
hMenu: DWORD//待赋予的菜单资源的句柄; 若为0,则删除窗口当前已有的菜单
如果函数执行成功,则返回非 0; 否则返回 0
载入光标
LoadCursor PROTO
hInstance : DWORD//应用程序实例句柄
lpCursorName : DWORD//光标的名字或光标资源的标识符
如果函数执行成功, 则返回刚装入的光标的句柄; 否则返回0
当hInstance为0时,可以装入系统预定义光标,即可以将lpCursorName的值赋为:IDC_ARROW(标准箭头), IDC_WAIT(时间瓶光标)或 IDC_CROSS(X 形光标)等
获得用户去窗口大小
GetClientRect PROTO
hWnd : DWORD//被检取坐标的用户区所在的窗口句柄
lpRect: DWORD//指向一个存放用户区坐标的RECT结构
- 如果函数执行成功,则返回非0; 否则返回0。
- 用户区坐标指定用户矩形区域的左上角和右下角的坐标。
- RECT的结构定义顺序为: left、top、right、bottom
初始化公用控件
InitCommonControls PROTO
该函数将公用控件动态库装入系统供程序使用,它没有输入参数和返回值
消息循环
获取消息
GetMessage PROTO
lpMsg : DWORD //指向一个MSG结构变量的指针
hWnd : DWORD //消息所属窗口的句柄
wMsgFilterMin : DWORD//指定被检取的最低消息值的整数值
wMsgFilterMax : DWORD//指定被检取的最高消息值的整数值
该函数只检取与给定窗口有关并且位于给定消息值范围内的消息。 如果检取到退出消息WM_QUIT,则返回值为0,否则,返回非0并将消息信息填到 lpMsg指向的结构变量中
转换键盘消息
TranslateMessage PROTO
lpMsg : DWORD //指向一个MSG结构变量的指针
该函数主要是为了将键盘输入数据转换成对应的ASCII码并产生WM_CHAR消息(该消息的wParam参数的低8位保存着对应键的ASCII码,lParam参数保存着键的其他相关信息)
若完成一个字符消息的转换,则返回非0,否则返回0
分发消息
DispatchMessage PROTO
lpMsg : DWORD //指向一个MSG结构变量的指针
该函数将lpMsg指向的消息传送到窗口过程(窗口消息处理函数wdProc) 返回值通常被忽略
窗口过程中使用的API函数
消息处理函数
显示消息框
MessageBoxA PROTO
hWnd : DWORD //该消息框所属窗口的句柄,为0时,表示没有所属窗口
lpText : DWORD//待显示字符串(结束符为 0)的首地址指针
lpCaption : DWORD//消息框标题字符串(结束符为0)的首地址指针; 为0时显示标题Error
uType : DWORD//指定消息框的样式
返回值为0表示没有足够的内存空间来创建该消息框
非0则表示用户按下的按钮号
该函数在屏幕上创建、显示一个消息框,并在其中显示各种字符串和多种图标,还提供了多种可供选择操作的按钮。 参数uType指定了在消息框中要显示哪些按钮和图标。 常用的按钮选项有:
- MB_OK:仅显示确认按钮,其值为0
- MB_OKCANCEL:同时显示确认和取消按钮,其值为1
- MB_YESNOCANCEL:同时显示是、否和取消按钮,其值为3
显示字符串
TextOut PROTO
hdc : DWORD //设备上下文句柄
nXStart : DWORD//起始显示位置的 X 坐标
nYStart : DWORD//起始显示位置的 Y 坐标
lpString : DWORD//待显示字符串的地址
cbString : DWORD//串长度
该函数在显示设备上下文句柄hdc代表的窗口中显示lpString指示的存储区中的字符串,字符串在窗口中的起始位置的坐标为nXStart, nYStart, 显示的字符数由参数cbString决定。 若函数执行成功,则返回非0,否则返回0。 为了得到指定窗口的hdc,在调用TextOut之前,必须先调用GetDC函数
GetDC PROTO
hWnd : DWORD //指定窗口的句柄
该函数在执行成功时,返回指定窗口用户区的设备上下文句柄hdc,否则返回0。
发送消息
SendMessage PROTO
hWnd : DWORD//接收该消息的窗口的句柄
uMsg : DWORD//指定要发送的消息,它是消息的标识符
wParam : DWORD//第一个参数
lParam : DWORD//第二个参数
- 该函数把指定的消息发送给指定的窗口
- 消息的标识符可以自定义,也可以使用系统预定义的
下面是几个与编辑子窗口相关的预定义消息
- WM_SETTEXT:用以设置窗口中的文字
- WM_GETTEXT:把与一个窗口相联系的文字拷贝到由调用者提供的缓冲区中
- WM_GETTEXTLENGTH:获取与一个窗口相联系的文字的长度,以字符个数为单位
发送退出消息
PostQuitMessage PROTO
nExitCode : DWORD//退出码
- 该函数生成一个退出消息WM_QUIT并加入到所在程序的消息队列中用以终止消息循环
- 退出码nExitCode将赋给WM_QUIT消息的wParam参数
- 该函数没有返回值
消息的缺省出来函数
DefWindowProc PROTO
hWnd : DWORD//本窗口的句柄
uMsg : DWORD//消息的标识符
wParam : DWORD//第一个参数
lParam : DWORD//第二个参数
该函数将本窗口接收但未处理的消息交给操作系统,由操作系统按照缺省的方法进行处理
文件操作
- 对文件进行操作前,必须要打开或者创建,获取该文件的句柄
- 然后利用句柄和操作权限,进行读写,读写完后要关闭文件
打开和创建
CreateFile PROTO
lpFileName : DWORD//指向文件名字符串(结束符为0)的指针
dwDesiredAccess : DWORD//访问方式
dwShareMode : DWORD//共享方式
lpSecurityAttributes : DWORD//指向安全信息结构变量的指针
dwCreationDistributions : DWORD//创建方式
dwFlagsAndAttributes : DWORD//文件属性
hTemplateFile : DWORD//模板文件句柄
- 该函数打开或创建由lpFileName指向的字符串所描述的文件, 如果执行成功,则返回被打开文件的句柄; 否则返回INVALID_HANDLE_VALUE
- 访问方式可以是GENERIC_READ、GENERIC_WRITE、0(只允许获取与文件有关的信息)
- 共享方式用于控制该文件是否可以被多个程序同时打开和读写,取值为0(不共享),FILE_SHARE_READ(共享读),FILE_SHARE_WRITE(共享写)
- lpSecurityAttributes为0时表示该文件不能被子进程继承
- 创建方式的值为CREATE_NEW(创建新文件)、CREATE_ALWAYS(创建新文件,重写已存在的文件)、OPEN_EXISTING(打开文件)、OPEN_ALWAYS(打开,若不存在则创建)、TRUNCATE_EXISTING(将现有文件缩短到0)
- 文件属性常用值:FILE_ATTRIBUTE_ARCHIVE(标记归档属性)、FILE_ATTRIBUTE_HIDDEN(隐藏文件或目录)、FILE_ATTRIBUTE_READONLY(只读文件)、FILE_ATTRIBUTE_SYSTEM(系统文件)
- hTemplateFile如果不为零,则指定的是一个已经存在的文件句柄,本次创建的新文件将从这个模板文件中复制扩展属性
关闭
CloseHandle PROTO
hObject : DWORD//被关闭文件的句柄
调用后,如果EAX中的返回值为非0,则表示成功,为0则表示失败
读
ReadFile PROTO
hFile : DWORD//被读文件的句柄
lpBuffer : DWORD//用于保存读入数据的存储单元的指针
nNumberOfBytesToRead : DWORD//待读入的字节数
lpnumberOfBytesRead : DWORD//从文件中实际读入的字节数存放的地址
lpOverlapped : DWORD//指向一个OVERLAPPED结构,用于说明一次异步读取操作
写
WriteFile PROTO
hFile : DWORD//被写文件的句柄
lpBuffer : DWORD//待写数据的存储区指针
nNumberOfBytesToWrite : DWORD//待写入的字节数
lpnumberOfBytesWritten : DWORD//实际写入文件的字节数量
lpOverlapped : DWORD//指向一个OVERLAPPED结构,用于说明一次异步读取操作
获取文件长度
GetFileSize PROTO
hFile : DWORD//文件的句柄
lpFileSizeHigh : DWORD//指向一个变量,该变量用于存放文件大小的高位双字
该函数检取指定文件的字节大小
更多推荐
【x86汇编】第六章 输出/输出和win32编程
发布评论