Windows下控制檯輸出

控制檯輸出就象dos下的輸出,可不是圖形界面。象ping/ipconfig/ftp等命令都是這類程序。

    回憶過去,在dos下進行文件操作時,常用到“文件把柄”的概念,使用文件把柄操作時,非常方便,操作時,只要知道把柄號就可以,而不用操心文件的位置。dos下,設備也都有自己的專用把柄,這些把柄是:

0000H  標準輸入設備 (stdin)

0001H  標準輸出設備 (stdout)

0002H  標準錯誤設備 (stderr)

0003H  標準輔助設備 (stdaux)

0004H  標準打印設備 (stdprn)

stdin和stdout可以被再定向,dos下常用的“輸入改向”和“輸出改向”就是這個意思。

下面的dos功能調用中將向屏幕輸出信息:
mov ah,40h      ;寫到文件或設備

mov bx,1        ;標準輸出設備

lea dx,OutData  ;DS:DX->要輸出的數據

mov cx,Count    ;要輸出字符的個數

int 21h         ;執行dos功能調用

利用同樣的道理,在windows下,也可向屏幕輸出信息。這要用到兩個Api函數,一個是GetStdHandle,另一個是WriteFile,在Win32 developer's References中它們是這樣定義的:

------------------------------------------------------------
HANDLE GetStdHandle(
    DWORD nStdHandle    // input, output, or error device
    );  

The GetStdHandle function returns a handle for the standard input, standard output, or standard error device.

nStdHandle->Specifies the device for which to return the handle. This parameter can have one of the following values:
Value               |   Meaning
--------------------+---------------------------
STD_INPUT_HANDLE    |   Standard input handle
STD_OUTPUT_HANDLE   |   Standard output handle
STD_ERROR_HANDLE    |   Standard error handle

If the function succeeds, the return value is a handle of the specified device.
------------------------------------------------------------
BOOL WriteFile(
    HANDLE hFile,       // handle to file to write to
    LPCVOID lpBuffer,   // pointer to data to write to file
    DWORD nNumberOfBytesToWrite,        // number of bytes to write
    LPDWORD lpNumberOfBytesWritten,     // pointer to number of bytes written
    LPOVERLAPPED lpOverlapped   // pointer to structure needed for overlapped I/O
    );  


下面我們看一個程序,作用是顯示一個字符串信息!

.386
.model flat,stdcall
 option casemap:none

include windows.inc
include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib

.data
    mess    db 'How are you !',0    ;要顯示的信息

.data?
    StdOut  dd ?    ;存放標準輸出的把柄
   CharOut dd ?    ;記錄實際輸出的字符數

.code
    start:  
        invoke GetStdHandle,STD_OUTPUT_HANDLE   ;獲取標準輸出的把柄
        mov StdOut,eax      ;保存把柄號

        lea eax,mess
        invoke lstrlen,eax  ;求字符串的長度

        lea ecx,CharOut
        invoke WriteFile,StdOut,addr mess,eax,ecx,NULL  ;寫文件
        
        invoke ExitProcess,NULL   ;程序結束
end start

編譯鏈接,下面給出詳盡的信息,供分析參考:
D:\MASM7>dir /ad

Volume in drive D has no label
Volume Serial Number is 18F0-186B
Directory of D:\MASM7

.              〈DIR〉        02-12-03  17:36 .
..             〈DIR〉        02-12-03  17:36 ..
LIB            〈DIR〉       02-12-03  17:38 LIB
INCLUDE        〈DIR〉        02-12-03  17:38 INCLUDE
         0 file(s)              0 bytes
         4 dir(s)   2,411,925,504 bytes free

D:\MASM7>ml /coff /I include 4.asm /link /subsystem:console /libpath:lib
Microsoft (R) Macro Assembler Version 6.14.8444         └─ 控制檯程序
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

Assembling: 4.asm
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/subsystem:console /libpath:lib
"4.obj"
"/OUT:4.exe"

D:\MASM7>4
How are you !
D:\MASM7>

另外,在masm32.inc中有函數StdOut的聲明,可用來直接輸出信息,把上面的例子修改後就是下面的樣子,可見來得更簡煉,供大家參考:

.386
.model flat,stdcall
option casemap:none   ;case sensitive

include windows.inc
include kernel32.inc
include masm32.inc
includelib kernel32.lib
includelib masm32.lib

.data
    mess    db 'How are you !',0    

 .code
start:  
        invoke StdOut,addr mess
        invoke ExitProcess,NULL
end start

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章