我是靠谱客的博主 热心魔镜,最近开发中收集的这篇文章主要介绍汇编语言32位控制台读取用户输入字符程序代码分析(17),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

 

 

来自于《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)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部