汇编语言MS-Windows编程简述
/SUBSYSTEM:CONSOLE
控制台程序的外观和操作就像 MS-DOS 窗口,它的一些改进部分将在后面进行介绍。控制台有一个输入缓冲区以及一个或多个屏幕缓冲区:1) 输入缓冲区(input buffer):
包含一组输入记录(input records),其中的每个记录都是一个输入事件的数据。输入事件的例子包括键盘输入、鼠标点击,以及用户调整控制台窗口大小。2) 屏幕缓冲区(screen buffer):
是字符与颜色数据的二维数组,它会影响控制台窗口文本的外观。Win32 API 参考信息
函数
在接下来的讲解中将介绍 Win32 API 函数的子集并给岀一些简单的例子。由于篇幅的限制,将不会涉及很多细节。如果想了解更多信息,请访问 Microsoft MSDN 网站(地址为:www.msdn.microsoft.com)。在搜索函数或标识符时,把 Filtered by 参数设置为 Platform SDK。常数
阅读 Win32 API 函数的文档时,常常会见到常量名,如 TIME_ZONE_ID_UNKNOWN。少数情况下,这些常量已经在 SmallWin.inc 中定义过。例如,头文件 WinNT.h 就定义了 TIME_ZONE_ID_UNKNOWN 及相关常量:
#define TIME_ZONE_ID_UNKNOWN 0
#define TIME_ZONE_ID_STANDARD 1
#define TIME_ZONE_ID_DAYLIGHT 2
TIME_ZONE_ID_UNKNOWN = 0
TIME_ZONE_ID_STANDARD = 1
TIME_ZONE_ID_DAYLIGHT = 2
字符集和 Windows API 函数
调用 Win32 API 函数时会使用两类字符集:8 位的 ASCII/ANSI 字符集和 16 位的 Unicode 字符集(所有近期的 Windows 版本中都有)。Win32 函数可以处理的文本通常有两种版本:一种以字母 A 结尾(8 位 ANSI 字符),另一种以 W 结尾(宽字符集,包括了 Unicode)。WriteConsole 即为其中之一:
WriteConsoleA
WriteConsoleW
在 Microsoft MSDN 链接库的函数文件中,如 WriteConsole,尾字符 A 和 W 都被省略了。
WriteConsole EQU <WriteConsoleA>
这个定义使得程序能按 WriteConsole 的通用名对其进行调用。高级别和低级别访问
控制台访问有两个级别,这就能够在简单控制和完全控制之间进行权衡:- 高级别控制台函数从控制台输入缓冲区读取字符流,并将字符数据写入控制台的屏幕缓冲区。输入和输出都可以重定向到文本文件。
- 低级别控制台函数检索键盘和鼠标事件,以及用户与控制台窗口交互 ( 拖曳、调整大小等 ) 的详细信息。这些函数还允许对窗口大小、位置以及文本颜色进行详细控制。
Windows 数据类型
Win32 函数使用 C/C++ 程序员的函数声明进行记录。在这些声明中,所有函数参数类型要么基于标准 C 类型,要么基于 MS-Windows 预定义类型 (下表中列出了部分类型 ) 之一。MS-Windows 类型 | MASM类型 | 说明 |
---|---|---|
BOOL, BOOLEAN | DWORD | 布尔值 (TRUE 或 FALSE) |
BYTE | BYTE | 8 位无符号整数 |
CHAR | BYTE | 8 位 Windows ANSI 字符 |
COLORREF | DWORD | 作为颜色值的 32 位数值 |
DWORD | DWORD | 32 位无符号整数 |
HANDLE | DWORD | 对象句柄 |
HFILE | DWORD | 用 OpenFile 打开的文件的句柄 |
INT | SDWORD | 32 位有符号整数 |
LONG | SDWORD | 32 位有符号整数 |
LPARAM | DWORD | 消息参数,由窗口过程和回调函数使用 |
LPCSTR | PTR BYTE | 32 位指针,指向由 8 位 Windows (ANSI)字符组成的空字节结束的字符串常量 |
LPCVOID | DWORD | 指向任何类型的常量 |
LPSTR | PTR BYTE | 32 位指针,指向由 8 位 Windows (ANSI) 字符组成的空字节结束的字符串 |
LPCTSTR | PTR WORD | 32 位指针,指向对 Unicode 和双字节字符集可移植的字符串常量 |
LPTSTR | PTR WORD | 32 位指针,指向对 Unicode 和双字节字符集可移植的字符串 |
LPVOID | DWORD | 32 位指针,指向未指定类 |
LRESULT | DWORD | 窗口过程和回调函数返回的 32 位数值 |
SIZE_T | DWORD | 一个指针可以指向的最大字节数 |
UNIT | DWORD | 32 位无符号整数 |
WNDPROC | DWORD | 32 位指针,指向窗口过程 |
WORD | WORD | 16 位无符号整数 |
WPARAM | DWORD | 作为参数传递给窗口过程或回调函数的 32 位数值 |
区分数据值和指向值的指针是很重要的。以字母 LP 开头的类型名是长指针 (long pointer),指向其他对象。
SmallWin.inc 头文件
SmallWin.inc 是一个头文件,其中包含了 Win32 API 编程的常量定义、等价文本以及函数原型。通过本教程一直使用的 Irvine32.inc,SmallWin.inc 被自动包含在程序中。大多数常量都可以在用于 C 和 C++ 编程的头文件 Windows.h 中找到。与它的名字不同,SmallWin.inc 文件相当大, 因此这里只展示其突出部分:
DO_NOT_SHARE = 0
NULL = 0
TRUE = 1
FALSE = 0
;Win32 控制台句柄
STD_INPUT_HANDLE EQU -10
STD_OUTPUT_HANDLE EQU -11
STD_ERROR_HANDLE EQU -12
HANDLE TEXTEQU <DWORD>
SmallWin.inc 也包括用于 Win32 调用的结构定义。下面给出了两个结构定义:
COORD STRUCT
X WORD ?
Y WORD ?
COORD ENDS
SYSTEMTIME STRUCT
wYear WORD ?
wMonth WORD ?
wDayOfWeek WORD ?
wDay WORD ?
wHour WORD ?
wMinute WORD ?
wSecond WORD ?
wMilliseconds WORD ?
SYSTEMTIME ENDS
控制台句柄
几乎所有的 Win32 控制台函数都要求向其传递一个句柄作为第一个实参。句柄 (handle) 是 一个 32 位无符号整数,用于唯一标识一个对象,例如一个位图、画笔或任何输入/输岀设备:
STD_INPUT_HANDLE standard input
STD_OUTPUT_HANDLE standard output
STD_ERROR_HANDLE standard error output
GetStdHandle 函数返回一个控制台流的句柄:输入、输出或错误输出。基于控制台的程序中所有的输入/输出操作都需要句柄。函数原型如下:
GetStdHandle PROTO,
nStdHandle:HANDLE ;句柄类型
.data
inputHandle HANDLE ?
.code
INVOKE GetStdHandle, STD_INPUT_HANDLE
mov inputHandle;eax