我在一个非常简单的汇编语言中使用BEQ,NAND和ADD来创建SRL。我还必须将乘数保持在50行以下(到目前为止使用了16行),所以希望解决方案可以在循环中抛出。
编辑:我的问题是如何实现只有NAND和ADD的SRL
虽然效率非常低,但是有一个想法,也许有人可以改进它:
减少说,a,由1.将该值存储在b中。添加b和b并存储在c中。 Beq c with a,如果它是真的那么b是a的一半,也就是srl。唯一的问题是在某些情况下它必须循环数千次。仍然对其他想法持开放态度。
答案 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=1
,in_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.
右移不是那么明显。