1

SRL を作成するために BEQ、NAND、および ADD を使用する非常に単純なアセンブリ言語で乗算器を作成しています。また、乗数を 50 行 (これまでに使用したのは 16 行) 未満に保つ必要があるため、解決策をループでスローできることを願っています。

編集:私の質問は、NAND と ADD だけで SRL を実装する方法です。

非常に非効率的ですが、アイデアがありましたが、誰かがそれを改善できるかもしれません:

たとえば、a を 1 減らします。その値を b に格納します。b と b を加算して c に格納します。Beq c with a、それが true の場合、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

これは、あなたが持っている操作のみを使用するコードです(ANDには2つのNANDが必要で、BNEにはジャンプの前後にBEQが必要です)。

本当に右シフトが必要な場合は、shift と add の代わりに test と set で同じ種類のループを使用できます。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

右シフトは、2 つのビット マスクによって実現できます。 in_bit マスクによってアドレス指定されたビットをout_bit=1in_bit=1<<RSHIFTout_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 に答える