概述
来自于《Intel汇编语言程序设计》(第四版)第11章---------32位windows编程。
所谓控制台,就是我们平常在使用XP系统时,在运行框输入CMD之后出现的那个黑色画面,他看起来与DOS系统很相似,但是两者却完全不同。
32位控制台程序运行在保护模式下,而DOS却运行在实模式下。
另外两者使用的函数库也完全不同,Win32控制台程序使用的就是windows下的那些API,而DOS系统使用的却是BIOS和MS-DOS中断。
每个win32控制台程序有一个输入缓冲区还有一个或多个屏幕缓冲区,输入缓冲区我们可以看做一个输入流,里面包含了一个输入动作记录的队列,每个输入动作(键盘,鼠标)都会在输入缓冲区中产生一个记录。
现在我们来看一下这个程序,它读取用户输入的字符:
TITLE Read From the Console ( ReadConsole.asm )
; This program reads a line of input from standard input.
INCLUDE Irvine32.inc
BufSize = 80
.data
buffer BYTE BuffSize DUP(?),0,0
stdInHandle DWORD ?
bytesRead DWORD ?
.code
main PROC
; Get handle to standard input
INVOKE GetStdHandle , STD_INPUT_HANDLE
mov stdInHandle , eax
; Wait for user input
INVOKE ReadConsole , stdInHandle , ADDR buffer,
BufSize - 2 , ADDR bytesRead , 0
; Display the buffer
mov esi , OFFSET buffer
mov ecx,16 ; 16 bytes
mov ebx , TYPE buffer
call DumpMem
exit
main ENDP
END main
我们先回顾一下win32控制台程序相关的内容。
如果我们要对控制台进行操作,我们需要使用控制台函数,而几乎每个控制台函数都需要一个32位无符号整数类型的句柄来唯一确定一个对象,句柄的类型如下:
STD_INPUT_HANDLE ; 标准输入句柄
STD_OUTPUT_HANDLE ; 标准输出句柄
STD_ERROR_HANDLE ; 标准错误输出句柄
要想得到一个句柄,我们可以使用GetStdHandle函数,函数原型为:
GetStdHandle PROTO
nStdHandle : DWORD ; 句柄的类型
例如,我们可以使用如下方法得到句柄,并将句柄值保存起来:
.data
inputHandle DWORD ?
.code
INVOKE GetStdHandle , STD_INPUT_HANDLE
mov inputHandle , eax
而在本程序中,我们用到了一个ReadConsole函数,它用于将一个文本输入读取到缓冲区中,函数原型如下:
ReadConsole PROTO ,
handle : DWORD ; 输入句柄
pBuffer : PTR BYTE, ; 缓冲区地址指针
maxBytes : DWORD, ; 要读取的字符串数量
pBytesRead : PTR DWORD, ; 指向返回实际读取量大小的指针
notUsed: DWORD ; (保留)
程序其实非常简单:
; Get handle to standard input
INVOKE GetStdHandle , STD_INPUT_HANDLE ; 首先调用GetStdHandle 获得一个句柄
mov stdInHandle , eax ; 将句柄保存到变量stdInHandle 中
; Wait for user input
INVOKE ReadConsole , stdInHandle , ADDR buffer, ;这里为ReadConsole传递参数,其中BufSize - 2是因为我们要接受一个回车,它占用了 0Dh 和 0Ah 两个字节
BufSize - 2 , ADDR bytesRead , 0
; Display the buffer
mov esi , OFFSET buffer
mov ecx,16 ; 我们决定Dump出16个字节长度
mov ebx , TYPE buffer
call DumpMem ; Dump
当我们在控制台输入abcdefg之后的结果是:
61 62 63 64 65 66 67 0D 0A 00 00 00 00 00 00 00
可以看到缓冲区中的数据一共为9个,包括abcdefg和最后的用户按下回车键所产生的换行符和回车符。这时ReadConsole 函数的返回值pBytesRead中保存的也是9 。
下面我们来看单个字符的输入。
在控制台下输入单个字符与之前的程序有点不同,原书告诉我们控制台输入单字符要用以下步骤:
1.使用GetConsoleMode函数获取控制台的当前模式,将其暂时保存到一个变量中
2.使用GetConsoleMode来改变控制台的输入模式。
3.用ReadConsole函数读取一个字符
4.用SetConsoleMode函数将原先的模式恢复回去
其中GetConsoleMode和SetConsoleMode函数的原型如下:
GetConsoleMode PROTO,
hConsoleHandle : DWORD ; 输入或者输出句柄
lpMode : PTR DWORD ; 一个双字变量指针
SetConsoleMode PROTO,
hConsoleHandle : DWORD ; 控制台句柄
dwMode : DWORD ; 控制台模式标志位
然后是读取单个从键盘输入的字符的程序如下:
.data
saveFlags DWORD ? ; back up of flags
.code
; Get & save the current console input mode flags
INVOKE GetConsoleMode,
consoleInHandle,
ADDR saveFlags
; Clear all console flags
INVOKE SetConsoleMode,
consoleInHandle,
0 ; new flag values
; Read a single character from input
INVOKE ReadConsole,
consoleInHandle, ; console input handle
ADDR buffer, ; pointer to buffer
1, ; max characters to read
ADDR bytesRead,0 ; return value
; Restore the previous flags state
INVOKE SetConsoleMode,
consoleInHandle,
saveFlags
结束。
最后
以上就是热心魔镜为你收集整理的汇编语言32位控制台读取用户输入字符程序代码分析(17)的全部内容,希望文章能够帮你解决汇编语言32位控制台读取用户输入字符程序代码分析(17)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复