学 Win32 汇编[3]: 控制台下的几种输入、输出方式

来源:互联网 发布:苏州教师网络培训平台 编辑:程序博客网 时间:2024/05/19 01:11

在熟悉指令、伪指令和汇编语法的过程中, 首先需要的是输入、输出的手段.

 

下面是之前尝试出的控制台输入、输出的几种办法:

1、使用 MASM 提供的 StdIn、StdOut 函数;

2、使用系统 API:

3、使用微软 C 标准库 msvcrt.dll 中的 printf 函数.

--------------------------------------------------------------------------------

1、使用 MASM 的 Stdin 和 StdOut 函数:

--------------------------------------------------------------------------------

; Test3_1.asm

; 测试代码前应先建立一个控制台工程: 文件 -> 新建工程 -> Console App ...

 

.386

.model flat, stdcall

 

include masm32.inc

include kernel32.inc

includelib masm32.lib

includelib kernel32.lib

 

.data

       len   equ  6

.data?

       szText dw      ?

 

.code

start:

       invoke StdIn, addr szText,len

       invoke StdOut, addr szText

    ret ;ret 是用于子程序返回的指令, 这里用它代替 ExitProcess(在没有生成 Win32 窗口时是可以的)

end start

--------------------------------------------------------------------------------

2、使用系统 API 函数:

--------------------------------------------------------------------------------

 

; Test3_2.asm

 

.386

.model flat, stdcall

 

include windows.inc

include kernel32.inc

includelib kernel32.lib

 

.data?

 

       hInput            dd    ?

       lpszBuffer       db    50 dup(?)

       hOut              dd    ?

       bRead            dd    ?

 

.code

start:

 

    invoke GetStdHandle,STD_INPUT_HANDLE      ; 获取控制台输入设备的句柄

    mov hInput, eax

 

    invoke SetConsoleMode,hInput,ENABLE_LINE_INPUT or /

                                 ENABLE_ECHO_INPUT or /

                                 ENABLE_PROCESSED_INPUT

 

    invoke ReadFile,hInput,addr lpszBuffer,sizeof lpszBuffer,ADDR bRead,NULL

 

    ;mov eax, bRead

   

    invoke GetStdHandle, STD_OUTPUT_HANDLE ; 获取控制台输出设备的句柄

    

    mov hOut, eax                            ; 把获取到的句柄给变量 hOut

                                                      

    invoke WriteFile, hOut, addr lpszBuffer, sizeof lpszBuffer, NULL, NULL

           ; 输出到控制台, 参数分别是: 句柄、字符串地址、字符串长度、成功写入的字数、异步读写的结构

 

    ret

end  start

; 另外前面用到的StdIn、 StdOut 也基本就是这样实现的, 源码在: masm32/m32lib/stdin.asm 、masm32/m32lib/stdout.asm

--------------------------------------------------------------------------------

 

3、使用微软 C 标准库中的scanf、printf 函数; msvscrt.inc 把它声明做 crt_printf

--------------------------------------------------------------------------------

 

; Test3_3.asm

 

.386

.model flat, stdcall

 

include msvcrt.inc

includelib msvcrt.lib

 

.data

       szText     db    ?

       szFmt     db    '%s', 0

 

.code

start:

       invoke     crt_scanf,addr szFmt,addr szText

       invoke     crt_printf, addr szText

    ret

end start

--------------------------------------------------------------------------------

 

三种方法相比之下, 应推荐使用 C 函数 crt_printf; 因为它可以方便输出更多数据类型, 如:

--------------------------------------------------------------------------------

 

; Test3_4.asm

 

.model flat, stdcall

 

include msvcrt.inc

includelib msvcrt.lib

 

.data

       szFmtOut       db    'EAX=%d; ECX=%c; ',0ah,0dh,'szText=%s',0

       szFmtIn         db    '%s',0

       szText            db    'hello word!',0

.code

start:

    mov eax, 11

    mov ecx, 65

    invoke     crt_scanf, addr szFmtIn,addr szText   

    invoke     crt_printf, addr szFmtOut, eax, ecx, addr szText

    ret

end start

--------------------------------------------------------------------------------