概要

PIC18には割り算命令はありません。引き戻し法で除算すると非常に時間が掛かります。
定数であれば乗算により高速に計算できます。
ここでは16bitを10で割ってみます。除算は逆数を乗ずることで求められます。例えば65536/10=6554倍にして16bit右へずらせば近い商が計算できます。
若干の誤差が生じますので仮の商に除数を乗じて非除数との差が10以上であれば商に1加算し、先ほどの差に10を加算します。
35命令サイクル+30命令サイクル(16bit*16bit)+14命令サイクル(16bit*8bit)=79命令サイクル(64MHz 4.94μs)となります。
汎用の16bit/8bitで計算する場合、最悪336命令サイクルですので、4.2倍ほど高速となります。1秒間に約202000回の除算ができることになります。
被除数はDIV_A16、除数は10固定です。商はMUL_A16,余りはDIV_A16に格納されます。
データの並び順はリトルエンディアンです。
答えを表示するプログラムは記載していないのでエミュレーター上で実行してください。
12345÷10の実行例を示します。商の1234と余りの5が得られています。

使用メモリは以下のとおりです。
プログラムサイズ 175byte
アクセスバンク 17byte

プログラムの説明

ソースファイル

以下のファイルで構成されている
div16_10da.asm ・・・ メインプログラム

ソースファイルのダウンロード div16_10da.zip

; 乗算による除算 16bit/10=16bit  Version 1.00
; 2017/01/09
; PIC18
; MPLAB X IDE v3.45 Microchip MPASM(v5.70)

#INCLUDE <p18f46k22.inc>	
        ; 水晶発振(16MHz) クロック分周無 PLL有効(*4) プライマリクロック有効  ウォッチドッグタイマ無効 低電圧プログラム書き込みモード無効
        CONFIG FOSC = HSHP,PLLCFG=ON,PRICLKEN=ON,WDTEN=OFF,LVP=OFF

bank0       UDATA_ACS

DIV_A16     RES     2 ; 除算の被除数を指定 サブルーチンコール後答えが返る
DIV_M16     RES     2 ; サブルーチンコール後余りが返る
DIV_B       RES     1 ; 除算の除数を指定
DIV_A16T    RES	    2 ;
DIV_A16T2   RES	    2 ;

MUL16A	 RES	2   ;   乗算引数1
MUL8B		    ;   乗算引数2	    
MUL16B	 RES	2   ;   乗算引数2	    
MUL16DTC	    ;   乗算結果
MUL32DTC RES	4   ;   乗算結果 

        CODE
        ORG 0
        goto   start    ;   リセット時

DIV1	EQU d'12345' ; 被除数
DIV2	EQU d'10'    ; 除数
	
start
	movlw	LOW DIV1
	movwf	DIV_A16
	movlw	HIGH DIV1
	movwf	DIV_A16+1
	call	div16_d10
        bra    $

;       除算    DIV_A16 / 10  MUL16A:商 DIV_A16:余
;	2017/01/09
	
div16_d10   ;	16bit/10
	movff	DIV_A16,MUL16A
	movff	DIV_A16+1,MUL16A+1
	movlw	LOW ((d'65536')/(DIV2))
	movwf	MUL16B
	movlw	HIGH ((d'65536')/(DIV2))
	movwf	MUL16B+1
	call	mul16_16
	movff	MUL32DTC+2,MUL16A
	movff	MUL32DTC+3,MUL16A+1
	movlw	DIV2
	movwf	MUL8B
	call	mul16_8
	movf	MUL16DTC,w
	subwf	DIV_A16
	movf	MUL16DTC+1
	subwfb	DIV_A16+1
	movf	DIV_A16,w
	cpfsgt	MUL8B	; 10>wregのとき次の命令をスキップ
	bra	div16_d10_mod
	bra	div16_d10_exit
div16_d10_mod
	incf	MUL16A
	clrf	WREG
	addwfc	MUL16A+1
	movlw	DIV2
	subwf	DIV_A16
	clrf	WREG
	subwfb	DIV_A16+1
div16_d10_exit
	return
	
; 乗算サブルーチン(16bit * 8bit -> 24bit)
; MUL16DTC=MUL16A*MUL8B	
; 2017/01/08

mul16_8
	; 下位8bit*8bit
	movf	MUL16A,W
	mulwf	MUL8B
	movff	PRODL,MUL16DTC
	movff	PRODH,MUL16DTC+1
	; 上位8bit*8bit
	movf	MUL16A+1,W
	mulwf	MUL8B
	movf	PRODL,W
	addwf	MUL16DTC+1
	btfsc	STATUS,C
	incf	PRODH
	movf	PRODH,w
	movwf	MUL16DTC+2
	return
	
; 乗算サブルーチン(16bit * 16bit -> 32bit)
; MUL32DTC=MUL16A*MUL16B	
; 2017/01/09
	
mul16_16
	; 下位8bit*8bit
	movf	MUL16A,W
	mulwf	MUL16B
	movff	PRODL,MUL32DTC
	movff	PRODH,MUL32DTC+1
	; 上位8bit*8bit
	movf	MUL16A+1,W
	mulwf	MUL16B
	movf	PRODL,W
	addwf	MUL32DTC+1
	btfsc	STATUS,C
	incf	PRODH
	movf	PRODH,w
	movwf	MUL32DTC+2
	; 下位8bit*8bitH
	movf	MUL16A,w
	mulwf	MUL16B+1
	movf	PRODL,w
	addwf	MUL32DTC+1
	movf	PRODH,w
	addwfc	MUL32DTC+2
	; 上位8bit*8bitH
	movf	MUL16A+1,w
	mulwf	MUL16B+1
	movf	PRODL,w
	addwf	MUL32DTC+2
	btfsc	STATUS,C
	incf	PRODH
	movf	PRODH,w
	movwf	MUL32DTC+3
	return


        END