- UID
- 460236
- 帖子
- 19
- 主題
- 10
- 精華
- 0
- 積分
- 21
- 楓幣
- 661
- 威望
- 20
- 存款
- 0
- 贊助金額
- 0
- 推廣
- 0
- GP
- 11
- 閱讀權限
- 10
- 性別
- 保密
- 在線時間
- 16 小時
- 註冊時間
- 2024-10-12
- 最後登入
- 2024-11-21
|
本帖最後由 ikj78i 於 2024-11-19 08:54 編輯
編寫視窗程式比較麻煩,主控臺程式比較簡單,底下就是一個很簡單的主控臺程式,叫HELLO。
HELLO會在「命令提示字元」顯示「請輸入姓名:」,等使用者輸入名字之後,例如使用者輸入
「張三」,HELLO會顯示「張三,你好。」- .586
- .model flat,stdcall
- option casemap:none
- include c:\masm32\include\windows.inc
- include c:\masm32\include\kernel32.inc
- include c:\masm32\include\user32.inc
- includelib c:\masm32\lib\kernel32.lib
- includelib c:\masm32\lib\user32.lib
- ;*******************************************************************************
- .DATA
- hOut DD ?
- hIn DD ?
- dOut DD ?
- dIn DD ?
- szHello DB ",你好。",0
- szHint DB "請輸入姓名:",0
- szName DB 10 DUP (0)
- DB SIZEOF szHello DUP (0)
- ;*******************************************************************************
- .CODE
- ;-------------------------------------------------------------------------------
- main PROC
- ;取得「標準輸出裝置代碼」,並存於hOut變數內。主控臺程式的輸出與輸入必須獲得「標準
- ;輸出裝置代碼」與「標準輸入裝置代碼」。簡單的說,標準輸出裝置其實就是螢幕;標準輸
- ;入裝置代碼,其實就是鍵盤。取得它們的代碼之後,才能對螢幕、鍵盤進行輸出、輸入
- invoke GetStdHandle,STD_OUTPUT_HANDLE
- mov hOut,eax
- ;取得「標準輸入裝置代碼」,並存於hOut變數內。
- invoke GetStdHandle,STD_INPUT_HANDLE
- mov hIn,eax
- ;在螢幕上顯示「請輸入姓名:」。對螢幕輸出文字需呼叫WriteConsole。
- ;第一個參數是標準輸出裝置代碼
- ;第二個參數是輸出文字的位址所在,並不是文字本身,用OFFSET可以取得變數的位址,所以
- ; OFFSET szHint就是取得szHint字串變數的位址。
- ;第三個參數是要顯示的字串長度,用SIZEOF可以取得字串長度。
- ;第四個參數是位址,此位址將存放WriteConsole實際輸出多少位元組
- ;第五個參數是系統保留給將來擴充所需,應設為0
- invoke WriteConsole,hOut,OFFSET szHint,SIZEOF szHint,OFFSET dOut,0
- ;讀取使用者用鍵盤輸入的文字。呼叫ReadConsole可讀取鍵盤輸入的文字,它的五個參數與
- ;WriteConsole很相似。要注意的是ReadConsole會對所讀取的文字之後自動加上兩個數值,
- ;13及10,這兩個數值代表換行
- invoke ReadConsole,hIn,OFFSET szName,SIZEOF szName,OFFSET dIn,0
- ;取得13、10的位址。szName的位址加上實際輸入幾個位元組就是13、10之後的位址。假如
- ;szName在100的位址上,輸入John之後有4個位元組,再加上13,10,所以dIn=6:
- ;100 101 102 103 104 105 106
- ; J o h n 13 10
- mov edx,OFFSET szName-2 ;EDX=100-2=98
- add edx,dIn ;EDX+dIn=104
- mov BYTE PTR [edx],0 ;把換行符號變為0
- ;要連接兩個字串,一般呼叫lstrcat,它可以把兩個字串以零為結尾連接起來,呼叫方式如下:
- ; invoke lstrcat,psz1,psz2
- ;psz1、psz2是字串位址,不是字串名稱。p代表指標也就是位址,s是字串,z代表零。lstrcat
- ;會把psz2所指位址上的字串複製到psz1位址上的字串之後,psz1上的字串結尾的0會被除去
- ;不可使用「invoke lstrcat,szName,szHello」,這樣會把szName、szHello的內容傳給lstrcat
- ;,但lstrcat要的不是字串內容而是位址。取得字串的位址,需用OFFSET。
- invoke lstrcat,OFFSET szName,OFFSET szHello
- ;最後呼叫WriteConsole,印出lstrcat連接後的字串,字串長度應等於使用者輸入的名字長度加
- ;上szHello的長度。使用者輸入的名字長度已經在dIn內,但須扣除13、10兩個位元組。szHello
- ;的長度可用SIZEOF szHello求得,但須扣除結尾的0。所以下式須減去3
- add dIn,SIZEOF szHello-3
- invoke WriteConsole,hOut,OFFSET szName,dIn,OFFSET dOut,0
- ;Windows應用程式要結束時,呼叫ExitProcess,0是傳回值,傳給Windows
- invoke ExitProcess,0
- main ENDP
- ;*******************************************************************************
- END main
複製代碼 把上述程式存入E:\TEMP\HELLO.ASM,開啟「命令提示字元」,輸入下面指令:
path c:\masm32\bin;%path%
ml /coff hello.asm /link /subsystem:console
就能看到組譯成功,輸入hello就能執行hello.exe,結果如下圖(張三是使用者輸入的名字):
|
|