冰楓論壇
標題:
用組合語言求兩數的最大公因數
[打印本頁]
作者:
ikj78i
時間:
7 小時前
標題:
用組合語言求兩數的最大公因數
底下的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。
gcd_lcm.png
(9.56 KB, 下載次數: 0)
7 小時前
上傳
點擊文件名下載附件
最大公因數執行結果
歡迎光臨 冰楓論壇 (https://bingfong.com/)
Powered by 冰楓