匯編實現多字節乘除法
乘法
單片機的乘法本質是二進制的乘法,而乘法本身是通過加法實現的。多字節的乘法其實就是移位做加法。例如7x11,用二進制豎式表示如下圖:
可以看到,其實就是判斷乘數的每一位是1還是0,如果是1,則將被乘數左移相應的位數,最后相加即可得到乘積。
程序中可以將左移變為右移,進一步精簡代碼。
以下代碼使用PIC單片機的匯編指令實現。
;*******************************************************************************
; * 函數名稱: math_multiply
; * 說 明: 三字節乘三字節。
; * 中間變量: ax/bx/cx/mathcnt
; * 輸入參數: ax/bx, 乘數
; * 輸出參數: bx|ax, 積
;*******************************************************************************
math_multiply:
nop1
movf bx + 2,0,0
movwf cx + 2,0
movf bx + 1,0,0
movwf cx + 1,0
movf bx + 0,0,0
movwf cx + 0,0
clrf bx + 2,0
clrf bx + 1,0
clrf bx + 0,0
movlw .24 ;24次移位
movwf mathcnt,0
math_multiply_loop:
bcf STATUS,C,0
btss ax + 0,0,0
bra math_multiply_loop_next
movf cx + 0,0,0
addn bx + 0,1,0
movf cx + 1,0,0
addc bx + 1,1,0
movf cx + 2,0,0
addc bx + 2,1,0
math_multiply_loop_next:
rrfc bx + 2,1,0
rrfc bx + 1,1,0
rrfc bx + 0,1,0
rrfc ax + 2,1,0
rrfc ax + 1,1,0
rrfc ax + 0,1,0
decsz mathcnt,1,0
bra math_multiply_loop
ret
除法
二進制的除法和十進制的除法原理相同,都是從被除數的高位到低位不斷試商的過程。例如11/2,用二進制豎式表示如下圖:
;*******************************************************************************
; * 函數名稱: math_division
; * 說 明: 六字節除以三字節
; * 中間變量: ax/bx/cx/dx/mathcnt
; * 輸入參數: bx|ax, 被除數
; * 輸入參數: cx, 除數
; * 輸出參數: bx|ax, 商
; * 輸出參數: dx, 余數
;*******************************************************************************
math_division:
clrf dx + 2,0
clrf dx + 1,0
clrf dx + 0,0
movlw .48 ;48次移位
movwf mathcnt,0
math_division_loop:
bcf STATUS,C,0 ;最低位先置0
rlfc ax + 0,1,0 ;被除數高位移出到dx
rlfc ax + 1,1,0
rlfc ax + 2,1,0
rlfc bx + 0,1,0
rlfc bx + 1,1,0
rlfc bx + 2,1,0
rlfc dx + 0,1,0
rlfc dx + 1,1,0
rlfc dx + 2,1,0
movf cx + 0,0,0 ;移出的高位和除數比較
subn dx + 0,0,0
movf cx + 1,0,0
subb dx + 1,0,0
movf cx + 2,0,0
subb dx + 2,0,0
btss STATUS,C,0
bra math_division_less
movwf dx + 2,0
movf cx + 0,0,0
subn dx + 0,1,0
movf cx + 1,0,0
subb dx + 1,1,0
incf ax + 0,1,0 ;最低位置1
math_division_less:
decsz mathcnt,1,0
bra math_division_loop
ret