1

私は 2 つの 8 ビット数を乗算し、それらを 16 ビットの場所に格納して 255 より大きい結果を得ようとしています。これを達成する最速の方法は、シフトを使用することです。これは、rrcf 関数を介して実装し、bcf を使用して不要なキャリーをクリアしようとしました。

これがアイブが思いついたものです。すべてのコードにコメントを付けてみたので、私の思考プロセスを確認できます。私はPIC18とASMでのプログラミングの両方に一般的にかなり慣れていません。(うまくいけば)助けを提供するときは、そのことを覚えておいてください。MPLAB SIM を実行すると、カウンターが減少するだけです...?

これは、乗数の最後のビットが繰り返しテストされているためだと思います。これはゼロになるため、毎回追加命令をスキップします。BTFSC をビット 0 ~ 7 から段階的に移動するループの作成を手伝ってもらえますか? これが問題だと思いますが、コードがわかりません。私は本質的にmainを8回書くことができましたが、コードスペースを節約しようとしています

            LIST P=18F4550
            #include <P18F4550.INC>

            ;equates
            counter equ 0x00 ;set counter
            multiplicand equ 0x01 ;set multiplicand
            multiplier equ 0x02 ;set multiplier
            resultHigh equ 0x03 ;set resultHigh
            resultLow equ 0x04 ;set resultLow

            ;test program

            movlw d'100' ;move literal d'100' to wreg
            movwf multiplicand ;set multiplicand
            movlw d'400'       ;move literal d'400'
            movlw multiplier   ;set multiplier
            movlw d'8'         ;counter
            movwf counter      ;set counter

            main:
            btfsc multiplier, 0          ;test LSB if 0,skip next if 0
            addwf multiplier, resultLow  ;add if 1 to resultLow
            bcf STATUS,C                 ;clear carry flag
            rlcf multiplier              ;rotate multiplier left
            bcf STATUS,C                 ;clear carry
            rlcf resultLow               ;rotate resultLow w/ carry
            rlcf resultHigh              ;rotate resultHigh 
                                                                  ;w/carry from resultLow

            decf counter                 ;dec counter
            goto main                    ;repeat for 8 bits
            end
4

2 に答える 2

3

実際、PIC18 asmは、単一のCPUサイクル8*8符号なしハードウェア乗算をサポートしています。

   MOVLW 100
   MOVWF multiplicand
   MOVLW 33
;multiply multiplicand with WREG 
   MULWF multiplicand
;product is stored in registers PRODH:PRODL
于 2012-10-19T07:38:27.810 に答える
0

このコードには奇妙な点がいくつかあります。

  1. を使用したことがないのにmultiplicand、どうすればそれを掛けることができますか? あなたが書いたとき、それはコピペエラーでしたaddwf multiplier, resultLowか?2 つの数値の積の代わりに 1 つの数値の 2 乗を計算したい場合を除いて、論理的には、あるmultiplicandべき場所にあります。

  2. の最下位ビットをテストしますmultiplier。これは、そのビットをチェックする必要があるため理にかなっていますが、multiplier左にシフトして、そのビットを永久に 0 にします。正しくないようです。右シフトを行うか、代わりに最上位ビットをチェックする必要があります。

  3. 結果のシフトは、加算後に発生します。8 ビットの数値ではなく 1 ビットの数値 (たとえば 1 対 1) を乗算し、積に 1 が期待されるとします。したがって、結果に 1 を加算し、結果を左にシフトします。それだけで製品に 2 が得られます。それはどうして正しいのでしょうか。シフトと加算の順番を逆にしたらどうですか?

  4. 0になったときにループがどのように終了するかわかりませんcounter。あなたの CPU には詳しくありませんが、減分counterしてから無条件に に戻るように見えますmain。これが条件付きジャンプになる理由は何ですか?

次の疑似コードは、乗算の実行方法を示しています。

multiplier = multiplier_value
multiplicand = multiplicand_value

counter = 8
resultLow = 0
resultHigh = 0

main:

carry = 0
shift left: carry <- resultLow <- carry
shift left: carry <- resultHigh <- carry

carry = 0 ; you don't need to zero it here, actually
shift left: carry <- multiplier <- carry

if carry = 0, goto no_add

carry = 0
resultLow = resultLow + multiplicand + carry
resultHigh = resultHigh + 0 + carry

no_add:

counter = counter - 1
if counter ≠ 0, goto main
于 2012-10-19T01:29:38.410 に答える