【问题标题】:fast 8x8bit multiplication assembly pic18快速 8x8 位乘法程序集 pic18
【发布时间】:2012-10-18 17:49:28
【问题描述】:

我试图将两个 8 位数字相乘并将它们存储在 16 位位置以获得大于 255 的结果。完成此操作的最快方法是通过移位,我尝试通过 rrcf 函数实现并使用 bcf 清除不需要的携带。

这是我想出的。我试图评论所有代码,以便您能够看到我的思考过程。总的来说,我对 PIC18 和 ASM 编程都很陌生。在(希望)提供帮助时请记住这一点。我需要放在一个比现在更好的位置,当我运行 MPLAB SIM 时,我得到的只是计数器递减......?

我认为这是由于乘法器的最后一位被反复测试,这将是零,因此每次都跳过我的加法指令。你能帮我创建一个循环以从 0-7 位逐步移动 BTFSC 吗?我认为这是问题所在,但我无法弄清楚代码。我基本上可以写 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

【问题讨论】:

    标签: performance assembly pic pic18 8-bit


    【解决方案1】:

    其实PIC18 asm支持单CPU周期8*8无符号硬件乘法。

       MOVLW 100
       MOVWF multiplicand
       MOVLW 33
    ;multiply multiplicand with WREG 
       MULWF multiplicand
    ;product is stored in registers PRODH:PRODL
    

    【讨论】:

      【解决方案2】:

      这段代码有几个奇怪的地方:

      1. 你从不使用multiplicand,那么你怎么可能乘以它呢?你写addwf multiplier, resultLow时是不是复制粘贴错误?按照所有逻辑,multiplicand 应该在哪里,除非你想计算一个数字的平方而不是两个数字的乘积。

      2. 您测试multiplier 的最低有效位,这是有道理的,因为您需要检查它的位,但随后您将multiplier 向左移动,将该位永远变为0。似乎不对。您应该进行右移或检查最高有效位。

      3. 结果的移位发生在加法之后。假设您将 1 位数字而不是 8 位数字相乘,例如 1 乘 1,并且在乘积中期望 1。因此,您将结果加 1,然后将结果左移。仅此一项就为您提供了产品中的 2。这怎么可能是对的?颠倒 shift 和 add 的顺序怎么样?

      4. counter 达到 0 时,我看不到循环如何结束。虽然我不熟悉您的 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
      

      【讨论】:

      • 您永远不会添加乘数和被乘数,您只需添加结果。特别是在二进制中。如果你有 1001X1101
      • 你只会将 1101 + 00000 + 110100 + 110100 加在一起
      • 我正在用汇编语言编程,这是个混蛋。看起来你正在使用C?更简单
      • 我的错,1001+ 00000 +100100 +1001000***
      • 我不需要加上乘数和被乘数。用手做,看看为什么。其实,首先要学会用手乘法。然后看看你学到了什么,看看你如何把它变成代码。
      猜你喜欢
      • 1970-01-01
      • 2017-01-25
      • 1970-01-01
      • 2011-12-04
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 2011-08-25
      相关资源
      最近更新 更多