PIC18シリーズ割り算アセンブラルーチン

PIC18シリーズのアセンブラサブルーチン


2011-08-22

PIC18シリーズの割り算サブルーチン
 ・言語 MPLAB C18 インラインアセンブラ
 ・16ビット符号無し除算 32ビット符号無し除算
符号付きの演算をしたい場合は符号処理を加えるだけ、MPASMで使用したいときはasm~endasm内を切り取れば良い。
 dividend_XX  被除数 A/B のA
 divisor_XX   除数 A/B のB
 divans_XX   結果
 divwork_XX   割り算ルーチン内部変数
 divcounter_XX 割り算ルーチン内部変数
 bsr_save_XX  BSRレジスタ退避領域
0001  #pragma udata BANK1=0x100
0002 unsigned char dividend_16,dividend_16H;
0003 unsigned char divisor_16,divisor_16H;
0004 unsigned char divans_16,divans_16H;
0005 unsigned char divwork_16,divwork_16H;
0006 unsigned char div_counter_16;
0007 unsigned char bsr_save_16;
0008
0009 unsigned char dividend_32,dividend_32H,dividend_32HH,dividend_32HHH;
0010 unsigned char divisor_32,divisor_32H,divisor_32HH,divisor_32HHH;
0011 unsigned char divans_32,divans_32H,divans_32HH,divans_32HHH;
0012 unsigned char divwork_32,divwork_32H,divwork_32HH,divwork_32HHH;
0013 unsigned char div_counter_32;
0014 unsigned char bsr_save_32;
0015 #pragma udata
0016
0017 //-------------------------------------------------------------------------------
0018 // 16bit / 16bit division
0019 //-------------------------------------------------------------------------------
0020 unsigned short warizan_16x16(unsigned short dividend, unsigned short divisor)
0021 {
0022 union {
0023 unsigned short Wval;
0024 unsigned char Bval[2];
0025 } tmp;
0026
0027 tmp.Wval = dividend;
0028 dividend_16 = tmp.Bval[0];
0029 dividend_16H = tmp.Bval[1];
0030 tmp.Wval = divisor;
0031 divisor_16 = tmp.Bval[0];
0032 divisor_16H = tmp.Bval[1];
0033
0034 _asm
0035 MOVFF BSR,bsr_save_16
0036 MOVLB 1 // bank1
0037 MY_SB_DVD16X16:
0038 CLRF divwork_16H, BANKED
0039 CLRF divwork_16, BANKED
0040 MY_SB_DVD16X162:
0041 MOVLW 16
0042 MOVWF div_counter_16, BANKED
0043 MY_SB_DVD16X16LP:
0044 RLCF dividend_16H,0, BANKED
0045 RLCF divwork_16,1, BANKED
0046 RLCF divwork_16H,1, BANKED
0047 MOVF divisor_16,0, BANKED
0048 SUBWF divwork_16,1, BANKED
0049 MOVF divisor_16H,0, BANKED
0050 BTFSS STATUS,0, ACCESS
0051 INCFSZ divisor_16H,0, BANKED
0052 SUBWF divwork_16H,1, BANKED
0053 BC MY_SB_DVD16X16LP2
0054 MOVF divisor_16,0, BANKED
0055 ADDWF divwork_16,1, BANKED
0056 MOVF divisor_16H,0, BANKED
0057 BTFSC STATUS,0, ACCESS
0058 INCFSZ divisor_16H,0, BANKED
0059 ADDWF divwork_16H,1, BANKED
0060 BCF STATUS,0, ACCESS
0061 MY_SB_DVD16X16LP2:
0062 RLCF dividend_16,1, BANKED
0063 RLCF dividend_16H,1, BANKED
0064 DECFSZ div_counter_16,1,BANKED
0065 BRA MY_SB_DVD16X16LP
0066 MOVF dividend_16,0, BANKED
0067 movwf divans_16, BANKED
0068 movff dividend_16H,divans_16H
0069 MOVFF bsr_save_16,BSR
0070 _endasm
0071
0072 tmp.Bval[0] = divans_16;
0073 tmp.Bval[1] = divans_16H;
0074
0075 return tmp.Wval;
0076 }
0077
0078 //-------------------------------------------------------------------------------
0079 // 32bit / 32bit division
0080 //-------------------------------------------------------------------------------
0081 unsigned long warizan_32x32( unsigned long dividend, unsigned long divisor)
0082 {
0083 union {
0084 unsigned long LWval;
0085 unsigned char Bval[4];
0086 } tmp;
0087
0088 tmp.LWval = dividend;
0089 dividend_32 = tmp.Bval[0];
0090 dividend_32H = tmp.Bval[1];
0091 dividend_32HH = tmp.Bval[2];
0092 dividend_32HHH = tmp.Bval[3];
0093 tmp.LWval = divisor;
0094 divisor_32 = tmp.Bval[0];
0095 divisor_32H = tmp.Bval[1];
0096 divisor_32HH = tmp.Bval[2];
0097 divisor_32HHH = tmp.Bval[3];
0098
0099 _asm
0100 MOVFF BSR,bsr_save_32
0101 MOVLB 1 // bank1
0102 MY_SB_DIV_U_32X32:
0103 CLRF divans_32, BANKED
0104 CLRF divans_32H, BANKED
0105 CLRF divans_32HH, BANKED
0106 CLRF divans_32HHH, BANKED
0107 CLRF divwork_32, BANKED
0108 CLRF divwork_32H, BANKED
0109 CLRF divwork_32HH, BANKED
0110 CLRF divwork_32HHH, BANKED
0111 MOVF divisor_32HHH,0, BANKED
0112 IORWF divisor_32HH,0, BANKED
0113 IORWF divisor_32H,0, BANKED
0114 IORWF divisor_32,0, BANKED
0115 BZ MY_DIV_U_32X32_EXIT
0116 MOVLW 32
0117 MOVWF div_counter_32, BANKED
0118 MY_DIV_U_32X32_LOOP:
0119 BCF STATUS,0, ACCESS
0120 RLCF dividend_32,1, BANKED
0121 RLCF dividend_32H,1, BANKED
0122 RLCF dividend_32HH,1, BANKED
0123 RLCF dividend_32HHH,1,BANKED
0124 RLCF divwork_32,1, BANKED
0125 RLCF divwork_32H,1, BANKED
0126 RLCF divwork_32HH,1, BANKED
0127 RLCF divwork_32HHH,1, BANKED
0128 MOVF divisor_32HHH,0, BANKED
0129 SUBWF divwork_32HHH,0, BANKED
0130 BNZ MY_L // $ + 18
0131 MOVF divisor_32HH,0, BANKED
0132 SUBWF divwork_32HH,0, BANKED
0133 BNZ MY_L // $ + 12
0134 MOVF divisor_32H,0, BANKED
0135 SUBWF divwork_32H,0, BANKED
0136 BNZ MY_L // $ + 6
0137 MOVF divisor_32,0, BANKED
0138 SUBWF divwork_32,0, BANKED
0139 MY_L:
0140 BNC MY_DIV_U_32X32_SKIP
0141 MOVF divisor_32,0, BANKED
0142 SUBWF divwork_32,1, BANKED
0143 MOVF divisor_32H,0, BANKED
0144 BTFSS STATUS,0, ACCESS
0145 INCFSZ divisor_32H,0, BANKED
0146 SUBWF divwork_32H,1, BANKED
0147 MOVF divisor_32HH,0, BANKED
0148 BTFSS STATUS,0, ACCESS
0149 INCFSZ divisor_32HH,0, BANKED
0150 SUBWF divwork_32HH,1, BANKED
0151 MOVF divisor_32HHH,0, BANKED
0152 BTFSS STATUS,0, ACCESS
0153 INCFSZ divisor_32HHH,0, BANKED
0154 SUBWF divwork_32HHH,1, BANKED
0155 BSF STATUS,0, ACCESS
0156 MY_DIV_U_32X32_SKIP:
0157 RLCF divans_32,1, BANKED
0158 RLCF divans_32H,1, BANKED
0159 RLCF divans_32HH,1, BANKED
0160 RLCF divans_32HHH,1, BANKED
0161 DECFSZ div_counter_32,1,BANKED
0162 BRA MY_DIV_U_32X32_LOOP
0163 MY_DIV_U_32X32_EXIT:
0164 MOVFF bsr_save_32,BSR
0165 _endasm
0166
0167 tmp.Bval[0] = divans_32;
0168 tmp.Bval[1] = divans_32H;
0169 tmp.Bval[2] = divans_32HH;
0170 tmp.Bval[3] = divans_32HHH;
0171
0172 return tmp.LWval;
0173 }
行番号
解説
1~15
変数定義 バンク1に変数を配置している
34~70
16ビット符号無し割り算。C言語の関数にしてあるがMPASMで使用したいときはこの部分だけを抜き取る。変数に値をセットしてこれを呼び出せば良い。
99~165
32ビット符号無し割り算。C言語の関数にしてあるがMPASMで使用したいときはこの部分だけを抜き取る。変数に値をセットしてこれを呼び出せば良い。
上のソースファイル
ファイル ファイルタイプ 添付ファイルの解説
warizan.c OTHER MPLAB C18
inserted by FC2 system