一種實用的單片機多字節(jié)除法程序
在單片機的實際應用中,除法運算是以比較常見的運算。
以MCS-51單片機為例,雖然提供了除法指令,但只能進行單字節(jié)的運算。如果要進行多字節(jié)的除法運算,就得自己設計算法。目前,許多資料上都介紹了四字節(jié)除以二字節(jié)的算法,但它們主要有以下幾點不足:
1. 只能求出商,不能求出余數;
2. 在被除數高二字節(jié)大于除數時,不能進行運算;
3. 商只有兩個字節(jié)。 例如,被除數是0FFFFFFFFH,除數是0004H時,商數應該是3FFFFFFFH,余數是0003H。
但是,用以前的算法是無法進行運算的。 在實際運用中,參與運算的數是任意的,有時需要求出余數,有時商數要求有四個字節(jié),因此,以前的算法在實際應用中受到了很大的限制。 為了滿足實際運用中的需要,有一套新的四字節(jié)除以二字節(jié)的算法,克服了上述算法中的缺點,可以適合廣泛的實際需要。下面以MCS-51匯編語言為例進行說明。 該算法增加了兩字節(jié)的余數單元,并把被除數單元用來存放商數。運算時,首先判斷除數是否為零,若為零時,則設溢出標志為1,然后退出。若除數不為零,則采用移位相減法進行運算。
首先,把進位位和余數單元清零。再將進位位、余數單元和被除數單元按順序首尾相連,逐位進行向左循環(huán)移位,共移位32次。每移位一次,余數單元都和除數作一次減法運算,若夠減,余數單元內容更新為兩者之差,并且將被除數最末一位置為1;若不夠減,則余數單元內容保持不變,且將被除數最末一位置為0。判斷是否夠減的方法是:在作減法之前,先保存進位位,再看作完減法后的進位位。僅在作減法之前進位位為0,并且作減法之后進位位為1時判為不夠減,其余情況均視為夠減。這樣,等到全部運算結束時,商數為四個字節(jié),存放在被除數單元中;余數為兩個字節(jié),存放在余數單元中。
例如,被除數是0FFFFFFFFH,除數是0004H時,運行新的算法,商數是3FFFFFFFH,存放在被除數單元中,余數是0003H,存放在余數單元中。 這個算法自然、流暢,運算結果商數為四個字節(jié),余數為兩個字節(jié),尤其是在求除以某數的N次方時,只需連續(xù)調用N次該算法子程序就可以了,省去了繁瑣的數據轉存語句。該算法還可以依實際需要擴充為位數更高的多字節(jié)除數算法,也可以移植到其它的單片機平臺上。
本算法已在AT89C51單片機上調試通過。下面給出算法的程序代碼清單。
divdll data 20h ;定義被除數單元divdlh data 21hdivdhl data 22hdlvdhh data 23hdivl data 24h ;定義除數單元divh data 25htempl data 26h ;定義余數單元temph data 27hdivd: push accpush bmov a,divdh ;判除數是否為零orl a,divljnz divd0setb ov ;除數為零,置溢出標志pop bpop accretdivd0: mov templ,#00h ;除數不為零,進行運算mov temph,#00hmov b,#20h ;置循環(huán)次數divd1:clr c ;進位位、余數單元和mov a,divdll ;被除數單元全體逐個rlc a ;向左循環(huán)移位mov divdll,amov a,divdlhrlc amov divdlh,amov a,divdhlrlc amov divdhl,amov a,divdhhrlc amov divdhh,amov a,templrlc amov templ,axch a,temphrlc axch a,temphmov f0,c ;保存進位位clr csubb a,divl ;用余數減去除數mov r7,amov a,temphsubb a,divh jc divd2 mov templ,r7 ;夠減,刷新余數單元mov temph,ainc divdll ;商上1divd2: djnz b,divd1clr ovpop bpop accretend
評論