1

老师给了我们一个作业,让我们编写一个程序,将 2 个 8 位长度的数字相乘。我们的微控制器仅支持 8 位寄存器,因此必须将结果放入 2 个寄存器中。这就是我卡住的地方。

要将这两个数字相乘,我必须将其中一个向左移动。而且我不知道该怎么做,因为当向左移动时,只剩下进位位,我可以将数字粘贴到其中,但是当我必须移动不止一位时,进位-有点不够。

我也不明白如何添加这些数字。例子:

Number1:    Number2:
0000'0111 * 1111'1111
---------------------
            1111'1111
          1'1111'111<  The 1 number on the left would be outside the register.
         11'1111'11<<  The 2 numbers on the left would be outside the register.
         ------------
        110'1111'1001

这是纸上的方法。但是我该如何实现呢?

4

3 回答 3

1

步行方式如下。调用两个寄存器 R_h 和 R_l,并初始化为 0。创建一个掩码 M_l := 0x01。调用被乘数寄存器x,乘数寄存器y。您还将使用寄存器 R_t.. 然后,在伪代码中:  

(0) 设 i = 0, j =8 

(1) 迭代 8 次 (i)

(2) 如果 (and x, M_l) == 0,则转到 (8)

(3)(a) sll y, i, 并保存在 R_t

(3)(b)添加R_l,R_t,存入R_l

(4) 如果进位位未设置,转到(6)

(5) 加R_h, 1

(6) srl y, j, 并存储在 R_t 中。这就是您从调整位置推入 R_h 的内容(保持 y 中的值不变)。 

(7) 添加 R_h、R_t,并存储在 R_h 中(您的中间结果现在是正确的)。

(8) i++, j--

(9) sll M_l, 1

(10) 跳跃 (1)

我很容易出现一个错误;但原则上,这应该有效。可能有一个标准算法,但这就是我想到的。 

于 2013-11-10T18:07:35.787 回答
1

请注意,当您将 X 添加到 (X << n) 时,和的最后 n 位不会改变:

因此,当您需要添加

  |ABCDEFGH
 A|BCDEFGH0  <-- the value shifted by 1, A doesn't fit in the 8-bit registers
 ----------
 c|xxxxxxxH  <-- you have the last bit 

将其转换为:

      |0ABCDEFG (H) is shifted out, that's one more correct bit of the result
      |ABCDEFGH
     ----------
 (C) + xxxxxxxx  <-- you get 8 bit of result + Carry

重复这 8 次将导致 8 个最低有效位移出,并将结果的 8 个最高有效位存储在累加器中。在每一轮中,进位实际上将替换上排的“0”:

     Partial sum = (c) | xxxxxxxX

     Shift PS >> 1 -->  Partial sum = cxxxxxxx | C <= X

这当然依赖于明智地实现的体系结构(存在通过进位指令的右循环)。

另一个选项包括将操作数拆分为部分,这些部分可以在本机相乘而不会溢出。给定一个可以容纳任何值 0<= x<= 100 的“处理器”,您可以乘以 2 位数字甚至更大:

    78 * 65 == 7*6 (*10^2) + 7*5 * (10^1) + 8*6 * (10^1) + 8*5

在微控制器中乘以(小)数的选项包括 x^2 表:

a*b = ((a+b)^2 - (a-b)^2) / 4 =
      ((a+b / 2)) ^ 2 - ((a-b)/2)^2 + A,
      where A an adjustment term just too difficult to remember, but possible
      to derive if needed.
于 2013-11-10T19:00:49.550 回答
1

我以某种方式解决了它,并且它有效。我真的很抱歉,我不能使用你的答案,我还是一个新手,不明白你写的很多东西。

我的解决方案:

Main:   

IN      Number1, SWITCH
IN      Number2_L, SWITCH2
CLR     Number2_H
CLR     Product_L
CLR     Product_H
Loop:   TST     Number1  ; Number1 > 0 ?
        BREQ    JEnd     ; If not, jump to JEnd
        LSR     Number1  ; Logical Shift Right to Carry
        BRCC    JNoC     ; If Carry not set, then jump to JNoC
        ADD     Product_L, Number2_L
        ADC     Product_H, Number2_H
JNoC:   LSL     Number2_L   ;Logical Shift Left to Carry
        ROL     Number2_H   ;Rotate Left through/from Carry
        RJMP    Loop        
JEnd:   OUT     LED, Product_L
        OUT     LED2, Product_H
        RJMP    Main      ; Infinite loop

笔记:

添加是 Rd <- Rd + Rr

ADC 为 Rd <- Rd + Rr + C

于 2013-11-10T20:08:56.363 回答