从ADD和NAND转向右逻辑?

时间:2013-02-12 03:55:43

标签: assembly add bit-shift

我在一个非常简单的汇编语言中使用BEQ,NAND和ADD来创建SRL。我还必须将乘数保持在50行以下(到目前为止使用了16行),所以希望解决方案可以在循环中抛出。

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

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

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

4 个答案:

答案 0 :(得分:3)

您实际上并不需要右移来实现乘法。看看如何做到这一点,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

答案 1 :(得分:1)

右移可以通过两个位掩码实现:out_bit=1in_bit=1<<RSHIFT通过将in_bit掩码寻址的位复制到out_bit掩码寻址的位置 - 就像移位字节数组一样。 / p>

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。

答案 2 :(得分:1)

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

如果真的需要右移,你可以使用相同类型的循环测试和设置而不是移位和添加。 N-1次迭代需要移位N位。

#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;
}

答案 3 :(得分:0)

为了实现乘数,您需要逻辑左移,而不是右移。 左移只是乘以2.可以通过自己添加值来实现:

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

右移不是那么明显。