- UID
- 460236
- 帖子
- 17
- 主題
- 10
- 精華
- 0
- 積分
- 21
- 楓幣
- 659
- 威望
- 20
- 存款
- 0
- 贊助金額
- 0
- 推廣
- 0
- GP
- 11
- 閱讀權限
- 10
- 性別
- 保密
- 在線時間
- 15 小時
- 註冊時間
- 2024-10-12
- 最後登入
- 2024-11-20
|
底下的gcd_lcm.asm也是在windows作業系統下的主控臺程式:- .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
- include c:\masm32\include\shlwapi.inc ;內含 StrToInt 的原型
- includelib c:\masm32\lib\shlwapi.lib
- includelib c:\masm32\lib\kernel32.lib
- includelib c:\masm32\lib\user32.lib
- ;*******************************************************************************
- .DATA
- hOut DD ?
- hIn DD ?
- dOut DD ?
- dIn DD ?
- n1 DD ? ;第一個整數
- n2 DD ? ;第二個整數
- gcd DD ? ;最大公因數
- lcm DD ? ;最小公倍數
- sBuffer DB 60h dup (0)
- sHint DB "請輸正整數:"
- szFmt DB "%u與%u的最大公因數是%u,最小公倍數是%u",0
- ;*******************************************************************************
- .CODE
- ;-------------------------------------------------------------------------------
- input PROC
- ;顯示「請輸正整數:」的提示文字,並讓使用者輸入數字
- invoke WriteConsole,hOut,OFFSET sHint,SIZEOF sHint,OFFSET dOut,0
- invoke ReadConsole,hIn,OFFSET sBuffer,12,OFFSET dIn,0
- ;呼叫StrToInt把使用者輸入的數字變成數值。假如使用者輸入「123」,但在記憶體中
- ;並不是123這個數值,而是31h、32h、33h,這是因為鍵盤輸入的是字元,在電腦中每個
- ;字元(字元可視為一個字,也就是鍵盤上的英文母、阿拉伯數字等),都以一個數來表示
- ;,阿拉伯數字的1是用十六進位的31h表示,阿拉伯數字的2是用十六進位的32h表示,依
- ;此類推,其中的h代表此數為十六進位,b代表二進位,d代表十進位,若數字後沒這些
- ;英文字代表十進位。StrToInt的功用就是把31h、32h、33h轉換為123。
- ;StrToInt只有一個參數,就是這些文字的位址,轉換後結果存於EAX裏
- invoke StrToInt,OFFSET sBuffer
- ret
- input ENDP
- ;-------------------------------------------------------------------------------
- ;利用輾轉相除法求num1、num2的最大公因數。在invoke fnd_gcd,n1,n2之後,n1、n2會分別
- ;存於num1、num2內,在fnd_gcd副程式內,最好使用num1、num2。
- fnd_gcd PROC num1:DWORD,num2:DWORD
- mov ecx,num1 ;輾轉相除法的過程是兩數相除後,如果有餘數,那麼下次的除數
- mov edx,num2 ;是這次的餘數,被除數是這次的除數,再進行除法,直到餘數為
- cmp ecx,edx ;零為止,最後一次的除數就是最大公因數
- jb below ;比較兩數何者較小
- again: xchg ecx,edx ;較小的當除數存於ECX,較大的當被除數存EDX
- below: mov eax,edx ;把被除數放在EAX
- xor edx,edx ;使EDX變為0
- div ecx ;EAX除以ECX得商為EAX,餘數為EDX
- or edx,edx ;檢查餘數EDX是否為0
- jnz again ;若不為零,還須再次進行除法,經過除法後,餘數(EDX)一定比除數(ECX)小
- mov eax,ecx ;若為零,傳回最後除數即為最大公因數
- ret
- fnd_gcd ENDP
- ;-------------------------------------------------------------------------------
- main PROC
- invoke GetStdHandle,STD_OUTPUT_HANDLE
- mov hOut,eax
- invoke GetStdHandle,STD_INPUT_HANDLE
- mov hIn,eax
- ;輸入第一個整數,存於n1
- call input
- mov n1,eax
- ;輸入第一個整數,存於n2
- call input
- mov n2,eax
- ;計算n1、n2的最大公因數,存於gcd內
- invoke fnd_gcd,n1,n2
- mov gcd,eax
- ;計算n1、n2的最小公倍數,存於lcm內
- mov eax,n1
- mul n2
- div gcd
- mov lcm,eax
- ;wsprintf會根據szFmt字串的格式,把n1、n2、gcd、lcm存於sBuffer內。這四個數值會變
- ;成數字字串。假設n1是123,那麼在sBuffer內是31h、32h、33h。szFmt內的%u代表無號數
- ;,可以把無號數是為正數。wsprintf的傳回值是在sBuffer存入多少位元組,此位元組數
- ;會放在EAX傳回
- invoke wsprintf,OFFSET sBuffer,OFFSET szFmt,n1,n2,gcd,lcm
- invoke WriteConsole,hOut,OFFSET sBuffer,eax,OFFSET dOut,0
- invoke ExitProcess,0
- main ENDP
- ;*******************************************************************************
- END main
複製代碼 把它存成gcd_lcm.asm,照下圖淡藍色字輸入指令組譯後,就可執行。
要注意,gcd_lcm並沒有檢查使用者輸入的數值大小所以輸入的數值太大時會出錯,兩數最好要小餘65000。
|
|