匯編實現多字節乘除法


匯編實現多字節乘除法

乘法

單片機的乘法本質是二進制的乘法,而乘法本身是通過加法實現的。多字節的乘法其實就是移位做加法。例如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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM