冰楓論壇

 找回密碼
 立即註冊
搜索
查看: 50|回覆: 0
打印 上一主題 下一主題

[心得] 簡單的Windows主控臺程式

[複製鏈接]

9

主題

0

好友

20

積分

新手上路

Rank: 1

UID
460236
帖子
16
主題
9
精華
0
積分
20
楓幣
624
威望
19
存款
0
贊助金額
0
推廣
0
GP
10
閱讀權限
10
性別
保密
在線時間
14 小時
註冊時間
2024-10-12
最後登入
2024-11-19
跳轉到指定樓層
1
發表於 5 小時前 |只看該作者 |倒序瀏覽
本帖最後由 ikj78i 於 2024-11-19 08:54 編輯

編寫視窗程式比較麻煩,主控臺程式比較簡單,底下就是一個很簡單的主控臺程式,叫HELLO。
HELLO會在「命令提示字元」顯示「請輸入姓名:」,等使用者輸入名字之後,例如使用者輸入
「張三」,HELLO會顯示「張三,你好。」
  1. .586
  2. .model  flat,stdcall
  3. option  casemap:none
  4. include    c:\masm32\include\windows.inc
  5. include    c:\masm32\include\kernel32.inc
  6. include    c:\masm32\include\user32.inc
  7. includelib c:\masm32\lib\kernel32.lib
  8. includelib c:\masm32\lib\user32.lib
  9. ;*******************************************************************************
  10. .DATA
  11. hOut    DD      ?
  12. hIn     DD      ?
  13. dOut    DD      ?
  14. dIn     DD      ?
  15. szHello DB      ",你好。",0
  16. szHint  DB      "請輸入姓名:",0
  17. szName  DB      10 DUP (0)
  18.         DB      SIZEOF szHello DUP (0)
  19. ;*******************************************************************************
  20. .CODE
  21. ;-------------------------------------------------------------------------------
  22. main    PROC
  23.   ;取得「標準輸出裝置代碼」,並存於hOut變數內。主控臺程式的輸出與輸入必須獲得「標準
  24.   ;輸出裝置代碼」與「標準輸入裝置代碼」。簡單的說,標準輸出裝置其實就是螢幕;標準輸
  25.   ;入裝置代碼,其實就是鍵盤。取得它們的代碼之後,才能對螢幕、鍵盤進行輸出、輸入
  26.         invoke  GetStdHandle,STD_OUTPUT_HANDLE
  27.         mov     hOut,eax
  28.   ;取得「標準輸入裝置代碼」,並存於hOut變數內。
  29.         invoke  GetStdHandle,STD_INPUT_HANDLE
  30.         mov     hIn,eax
  31.   ;在螢幕上顯示「請輸入姓名:」。對螢幕輸出文字需呼叫WriteConsole。
  32.   ;第一個參數是標準輸出裝置代碼
  33.   ;第二個參數是輸出文字的位址所在,並不是文字本身,用OFFSET可以取得變數的位址,所以
  34.   ;   OFFSET szHint就是取得szHint字串變數的位址。
  35.   ;第三個參數是要顯示的字串長度,用SIZEOF可以取得字串長度。
  36.   ;第四個參數是位址,此位址將存放WriteConsole實際輸出多少位元組
  37.   ;第五個參數是系統保留給將來擴充所需,應設為0
  38.         invoke  WriteConsole,hOut,OFFSET szHint,SIZEOF szHint,OFFSET dOut,0
  39.   ;讀取使用者用鍵盤輸入的文字。呼叫ReadConsole可讀取鍵盤輸入的文字,它的五個參數與
  40.   ;WriteConsole很相似。要注意的是ReadConsole會對所讀取的文字之後自動加上兩個數值,
  41.   ;13及10,這兩個數值代表換行
  42.         invoke  ReadConsole,hIn,OFFSET szName,SIZEOF szName,OFFSET dIn,0
  43.   ;取得13、10的位址。szName的位址加上實際輸入幾個位元組就是13、10之後的位址。假如
  44.   ;szName在100的位址上,輸入John之後有4個位元組,再加上13,10,所以dIn=6:
  45.   ;100 101 102 103 104 105 106
  46.   ; J   o   h   n   13  10
  47.         mov     edx,OFFSET szName-2     ;EDX=100-2=98
  48.         add     edx,dIn                 ;EDX+dIn=104
  49.         mov     BYTE PTR [edx],0        ;把換行符號變為0
  50.   ;要連接兩個字串,一般呼叫lstrcat,它可以把兩個字串以零為結尾連接起來,呼叫方式如下:
  51.   ;  invoke lstrcat,psz1,psz2
  52.   ;psz1、psz2是字串位址,不是字串名稱。p代表指標也就是位址,s是字串,z代表零。lstrcat
  53.   ;會把psz2所指位址上的字串複製到psz1位址上的字串之後,psz1上的字串結尾的0會被除去
  54.   ;不可使用「invoke lstrcat,szName,szHello」,這樣會把szName、szHello的內容傳給lstrcat
  55.   ;,但lstrcat要的不是字串內容而是位址。取得字串的位址,需用OFFSET。
  56.         invoke  lstrcat,OFFSET szName,OFFSET szHello
  57.   ;最後呼叫WriteConsole,印出lstrcat連接後的字串,字串長度應等於使用者輸入的名字長度加
  58.   ;上szHello的長度。使用者輸入的名字長度已經在dIn內,但須扣除13、10兩個位元組。szHello
  59.   ;的長度可用SIZEOF szHello求得,但須扣除結尾的0。所以下式須減去3  
  60.         add     dIn,SIZEOF szHello-3
  61.         invoke  WriteConsole,hOut,OFFSET szName,dIn,OFFSET dOut,0
  62.   ;Windows應用程式要結束時,呼叫ExitProcess,0是傳回值,傳給Windows
  63.         invoke  ExitProcess,0
  64. main    ENDP
  65. ;*******************************************************************************
  66. END     main
複製代碼
把上述程式存入E:\TEMP\HELLO.ASM,開啟「命令提示字元」,輸入下面指令:
path c:\masm32\bin;%path%
ml /coff hello.asm /link /subsystem:console
就能看到組譯成功,輸入hello就能執行hello.exe,結果如下圖(張三是使用者輸入的名字):



hello.png (8.51 KB, 下載次數: 2)

組譯HELLO並執行

組譯HELLO並執行

收藏收藏0 推0 噓0


把本文推薦給朋友或其他網站上,每次被點擊增加您在本站積分: 1彩票
複製連結並發給好友,以賺取推廣點數
簡單兩步驟,註冊、分享網址,即可獲得獎勵! 一起推廣文章換商品、賺$$
高級模式
B Color Image Link Quote Code Smilies |上傳

廣告刊登意見回饋關於我們管群招募本站規範DMCA隱私權政策

Copyright © 2011-2024 冰楓論壇, All rights reserved

免責聲明:本網站是以即時上載留言的方式運作,本站對所有留言的真實性、完整性及立場等,不負任何法律責任。

而一切留言之言論只代表留言者個人意見,並非本網站之立場,用戶不應信賴內容,並應自行判斷內容之真實性。

小黑屋|手機版|冰楓論壇

GMT+8, 2024-11-19 13:28

回頂部