`
qdujunjie
  • 浏览: 110343 次
  • 性别: Icon_minigender_1
  • 来自: Mars
社区版块
存档分类
最新评论

汇编语言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

 

 

结束。

分享到:
评论

相关推荐

    汇编语言 查找字符串中的指定字符程序设计 有源码

    通过上述分析可以看出,使用汇编语言编写字符串查找程序不仅能够提高程序的执行效率,还能深入了解计算机底层的工作原理。尽管汇编语言的学习曲线较陡峭,但它在某些特定领域仍然具有不可替代的优势。希望本篇文章能...

    汇编语言 4位数排序代码

    标题“汇编语言 4位数排序代码”表明本程序是用汇编语言编写,主要功能是对通过键盘输入的4位数进行排序。 #### 描述解读 描述部分提供了一些额外的信息:“由键盘输入4位数(不多于10个),并将这些数由大到小或由...

    《汇编语言课程设计案例精编》源代码

    《汇编语言课程设计案例精编》源代码包含了一系列与汇编语言相关的实践项目,旨在帮助学习者深入理解和掌握汇编语言编程技术。这个压缩包中的资源尤其关注电子时钟和动画时钟的设计,以及一个经典的asm版俄罗斯方块...

    汇编语言程序设计闰年的判断

    在计算机科学领域,汇编语言是一种低级编程语言,它与机器代码紧密相关,每条指令都对应着特定的机器语言操作。在这个“汇编语言程序设计闰年的判断”项目中,我们关注的是如何用汇编语言编写一个程序来识别闰年。 ...

    汇编对字符串加密并用16进制显示

    在本文中,我们将深入探讨如何使用Win32汇编语言对字符串进行加密,并将其结果显示为16进制格式。这涉及到几个关键概念,包括字符串处理、加密算法、16进制转换以及汇编指令的使用。 首先,让我们了解字符串处理在...

    16位汇编程序(寻找当前目录以及子目录下.txt文件中字符串)

    标题中的“16位汇编程序(寻找当前目录以及子目录下.txt文件中字符串)”表明这个程序是用16位汇编语言编写的,它的主要功能是在当前目录及其所有子目录下的所有.txt文本文件中查找特定的字符串,并对找到的字符串...

    汇编实验-分类统计字符个数

    在这个汇编语言实验中,学生被要求编写一个控制台程序,该程序能够接收用户输入的一串字符,并根据字符类型(字母、数字和其他字符)进行分类计数。具体来说,程序需要实现以下功能: 1. **数据结构与变量定义**: ...

    汇编语言中的dos中断整理,doc格式的。方便打印出来查阅

    在汇编语言中,DOS中断是与操作系统...这些DOS中断是汇编语言编程中基础且实用的操作,对于控制硬件设备、处理用户输入和文件管理至关重要。理解并熟练运用这些中断能够帮助开发者编写出直接与操作系统交互的高效程序。

    (汇编语言)(文件操作)(电话本)

    这个文件很可能是实现上述功能的汇编源代码,通过编译和链接后可以生成可执行程序。分析这个文件的代码可以帮助我们更深入地理解上述功能的具体实现。 6. **汇编语言专题实验报告n.doc**: 这可能是一个包含实验...

    南邮微机实验报告二(汇编语言)

    实验报告“南邮微机实验报告二(汇编语言)”主要关注的是使用汇编语言设计一个用户登录验证程序。该程序旨在通过控制台交互,验证用户输入的用户名和密码是否与预设值匹配,同时提供了对密码输入的隐藏处理。以下是...

    编程从键盘输入一个一位十六进制数,定义一个子程序将其以二进制形式输出到屏幕

    为了实现子程序设计,我们需要创建一个过程(在汇编语言中称为子程序或函数),这个过程接受一个字符作为参数,判断其是否为十六进制数,并返回对应的二进制表示。子程序通常包括局部变量声明、参数处理、计算逻辑和...

    汇编语言判断三角形

    当敲下回车后,子程读取字符结束,将进行三次判断三角形两边之和是否大于第三边。然后根据是否能构成三角形输出“Y”或者“N”。子程的最后恢复现场,通用寄存器的值依次出栈。程序结束。 程序运行结果如下图1所示,...

    Irvine32.inc[汇编]

    31. **ReadString** - 从控制台读取字符串。 32. **SetTextColor** - 设置控制台文本颜色。 33. **ShowFPUStack** - 将浮点数栈写入控制台窗口。 34. **StrLength** - 返回字符串长度。 35. **WaitMsg** - 等待用户...

    汇编实现的常驻内存时钟程序

    对于学习汇编语言的人来说,分析这个程序的源代码可以帮助理解如何直接与硬件交互,如何利用中断服务以及如何在内存中持久存储和更新数据。 总的来说,"汇编实现的常驻内存时钟程序"是一个很好的实践项目,它展示了...

    汇编时钟程序汇编时钟程序

    5. **显示和更新时间**:时钟程序需要将获取到的时间转换为人类可读的格式,并可能显示在控制台或图形用户界面中。这涉及到字符串处理、格式化和输出指令。 6. **循环和等待机制**:为了持续显示时间,程序需要包含...

    汇编语言实现的显示系统时间程序

    综上所述,这个汇编语言程序通过读取系统时间,将其格式化并显示在屏幕上,展示了汇编语言对硬件交互、内存管理和低级I/O操作的深入理解。实现这样的程序需要对计算机体系结构有深刻的认识,包括中断、定时器、内存...

    汇编 输出给定的无符号整数

    该实验不仅能够帮助学生掌握汇编语言的基本语法和结构,还能让他们了解微处理器的工作原理以及如何利用硬件资源进行简单的输入输出操作。 #### 实验目的 1. **熟悉汇编语言的基本指令**:学会使用常用的汇编语言...

    汇编小程序3

    【标题】:“汇编小程序3”是一个简单的编程任务,它要求我们使用汇编语言编写一个程序,该程序能够从键盘接收一个一位数的输入N,然后根据接收到的数字N响铃N次。这里的响铃是指在终端或控制台上模拟产生ASCII码为...

    汇编课程设计 包括很多的代码

    在本汇编课程设计中,我们将深入探讨编程的基础——汇编语言,以及如何利用它进行实际的项目开发。汇编语言是一种低级编程语言,它直接对应于计算机硬件的指令集,因此对于理解和控制计算机底层操作具有重要意义。...

Global site tag (gtag.js) - Google Analytics