山本ワールド
除算(引き戻し法) 24bit/8bit=24bit アセンブラプログラム
概要
PIC18には割り算命令はありません。引き戻し法で除算プログラム(24bit/8bit=24bit)を作成しました。
筆算と同じ方法で被除数の上位から除数を引き結果がマイナスになれば除数を足してもとに戻します。引き算結果がプラスの場合はビットに1を立てます。
以上の処理をビットをずらしながら16回実行すると商と余りを求めることができます。
計算時間は非常に時間がかかり、大雑把な計算では最悪26命令サイクル*24回=624命令サイクル(クロック64MHzで39μs)かかります。1秒間に約25000回程度しか計算できないことになります。
8086のDIV命令でDX:AX / reg16 -> DX:AXの場合、144~162クロック要します。10MHzの場合最悪16.2μsとなります。
H8 3048のDIVXU命令の場合22クロックです。(16MHz 1.375μs) 被除数はDIV_A24、除数はDIVL_Bに格納してからdiv24_8をコールします。商はDIV_A24,余りはDIV_M24に格納されます。
データの並び順はリトルエンディアンです。
答えを表示するプログラムは記載していないのでエミュレーター上で実行してください。以下に8338503/255=32700 余り 3の実行例を示します。
使用メモリは以下のとおりです。
プログラムサイズ 93byte
アクセスバンク 11byte(スタック4byte)
筆算と同じ方法で被除数の上位から除数を引き結果がマイナスになれば除数を足してもとに戻します。引き算結果がプラスの場合はビットに1を立てます。
以上の処理をビットをずらしながら16回実行すると商と余りを求めることができます。
計算時間は非常に時間がかかり、大雑把な計算では最悪26命令サイクル*24回=624命令サイクル(クロック64MHzで39μs)かかります。1秒間に約25000回程度しか計算できないことになります。
8086のDIV命令でDX:AX / reg16 -> DX:AXの場合、144~162クロック要します。10MHzの場合最悪16.2μsとなります。
H8 3048のDIVXU命令の場合22クロックです。(16MHz 1.375μs) 被除数はDIV_A24、除数はDIVL_Bに格納してからdiv24_8をコールします。商はDIV_A24,余りはDIV_M24に格納されます。
データの並び順はリトルエンディアンです。
答えを表示するプログラムは記載していないのでエミュレーター上で実行してください。以下に8338503/255=32700 余り 3の実行例を示します。
使用メモリは以下のとおりです。
プログラムサイズ 93byte
アクセスバンク 11byte(スタック4byte)
プログラムの説明
ソースファイル
以下のファイルで構成されているdiv24_8.asm ・・・ メインプログラム
ソースファイルのダウンロード div24_8.zip
; 除算(引き戻し法) 24bit/8bit=24bit Version 1.00
; 2017/01/08
; 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
STACK_MAX EQU d'4'
bank0 UDATA_ACS
DIV_A24 RES 3 ; 除算の被除数を指定 サブルーチンコール後答えが返る
DIV_M24 RES 3 ; サブルーチンコール後余りが返る
DIV_B RES 1 ; 除算の除数を指定
stack1 RES STACK_MAX ; スタックエリア
CODE
ORG 0
goto start ; リセット時
DIV1 EQU d'8338503'
DIV2 EQU d'255'
start
BANKSEL ANSELC
lfsr 2,stack1+(STACK_MAX-1) ; スタックの設定
movlw LOW DIV1
movwf DIV_A24
movlw HIGH DIV1
movwf DIV_A24+1
movlw UPPER DIV1
movwf DIV_A24+2
movlw DIV2
movwf DIV_B
call div24_8
bra $
; 除算 DIV_A24 / DIV_B 商はDIV_A24 余りはDIV_M24に返される
; 2017/01/08 FSR2で示されるスタックを1byte使用
div24_8 ; 24bit/8bit=24bit
clrf DIV_M24
clrf DIV_M24+1
clrf DIV_M24+2
movlw d'24'
div24_8_loop
movwf POSTDEC2
bcf STATUS,C
rlcf DIV_A24
rlcf DIV_A24+1
rlcf DIV_A24+2
rlcf DIV_M24
rlcf DIV_M24+1
rlcf DIV_M24+2
movf DIV_B,W
subwf DIV_M24 ; DIV_M24 < DIV_B -> C=0
clrf WREG
subwfb DIV_M24+1
subwfb DIV_M24+2
btfss STATUS,C
bra div24_8_non_sub
bsf DIV_A24,0
bra div24_8_shift
div24_8_non_sub
movf DIV_B,W
addwf DIV_M24
clrf WREG
addwfc DIV_M24+1,f
addwfc DIV_M24+2,f
div24_8_shift
movf PREINC2,W
decfsz WREG
bra div24_8_loop
return
END
Copyright (C) 2012 山本ワールド All Rights Reserved.