1

我正在用一种非常简单的汇编语言制作乘法器,其中我有 BEQ、NAND 和 ADD 来创建 SRL。我还必须将乘数保持在 50 行以下(到目前为止使用了 16 行),因此希望该解决方案可以循环使用。

编辑:我的问题是如何实现一个只有一个 NAND 和一个 ADD 的 SRL

有一个想法,虽然效率很低,但也许有人可以改进它:

将 a 递减 1。将该值存储在 b 中。添加 b 和 b 并存储在 c 中。Beq c 和 a,如果它是真的,那么 b 是 a 的一半,也就是 srl。唯一的问题是在某些情况下它必须循环数千次。仍然对其他想法持开放态度。

4

4 回答 4

4

你真的不需要右移来实现乘法。看看如何做到这一点,C 中的示例代码:

#include <stdio.h>

typedef unsigned char uint8;
typedef unsigned short uint16;

uint16 Mul8x8(uint8 a, uint8 b)
{
  int cnt;
  uint16 prod = 0;

  for (cnt = 8; cnt > 0; cnt--)
  {
    prod += prod;

    if (a & 0x80)
      prod += b;

    a += a;
  }

  return prod;
}

const uint8 Multipliers[][2] =
{
  { 0x00, 0x01 },
  { 0x01, 0x00 },
  { 0x33, 0x10 },
  { 0x11, 0x0C },
  { 0x0F, 0x0F },
  { 0x80, 0x80 },
  { 0xFF, 0xFF },
};

int main(void)
{
  int i;

  for (i = 0; i < sizeof(Multipliers) / sizeof(Multipliers[0]); i++)
  {
    uint8 a = Multipliers[i][0];
    uint8 b = Multipliers[i][1];

    uint16 p = a * b;
    uint16 p2 = Mul8x8(a, b);

    printf("0x%02X * 0x%02X = 0x%04X %c= 0x%04X\n",
           a, b, p, "!="[p == p2], p2);
  }

  return 0;
}

输出([ideone])(http://ideone.com/NwsykN)):

0x00 * 0x01 = 0x0000 == 0x0000
0x01 * 0x00 = 0x0000 == 0x0000
0x33 * 0x10 = 0x0330 == 0x0330
0x11 * 0x0C = 0x00CC == 0x00CC
0x0F * 0x0F = 0x00E1 == 0x00E1
0x80 * 0x80 = 0x4000 == 0x4000
0xFF * 0xFF = 0xFE01 == 0xFE01
于 2013-02-12T07:59:21.517 回答
1

这是一个仅使用您拥有的操作的代码(对于 BNE,您需要 2 个 NAND 用于 AND 和 BEQ 周围的跳转)。

如果你真的需要右移,你可以使用与 test 和 set 相同的循环,而不是 shift 和 add。移动 N 位需要 N-1 次迭代。

#include <stdio.h>

unsigned mult(unsigned x, unsigned y)
{
  unsigned test = 1, ans = 0;
next:
  if ((test & x) == 0) goto skip;
  ans += y;
skip: 
  y += y;
  test += test;
  if (test != 0) goto next;
  return ans; 
}

int main(void)
{
  unsigned x, y;
  while (1) {
    printf("Operands: ");
    if (scanf("%u%u", &x, &y) != 2) break;
    printf("Result: %u\n", mult(x, y));
  }
  return 0;
}
于 2013-02-13T06:14:37.673 回答
1

右移可以通过两个位掩码来完成:out_bit=1in_bit=1<<RSHIFT通过将 in_bit 掩码寻址的位复制到 out_bit 掩码寻址的位置——就像移位字节数组一样。

while (in_bit > 0) {
   if (word & in_bit) out_word+=out_bit;
   in_bit+=in_bit; out_bit+=out_bit;
}

与NAND一起操作,即。~(a & b), 有一个选项

do { 
   if (~(word & in_bit) == -1) { 
      out_word+=out_bit; 
   }
   in_bit+=in_bit; out_bit+=out_bit;
} while (!(in_bit==0));

现在只有运算符 ADD / NAND。

于 2013-02-12T07:14:56.647 回答
0

为了实现乘法器,您需要逻辑左移,而不是右移。左移就是简单的乘以2。可以通过自己加值来实现:

 a = a + a  ; this will produce the value shifted left. 

不过,右移并不是那么明显。

于 2013-02-12T07:04:54.563 回答