2013-02-12 90 views
0

我在一個非常簡單的彙編語言中創建了一個乘法器,其中我使用了BEQ,NAND和ADD來創建一個SRL。我還必須將乘數保持在50行以下(迄今爲止使用了16行),希望解決方案可以循環使用。僅從ADD和NAND的邏輯轉換?

編輯:我的問題是如何實現的SRL只有與非門和ADD

有一個想法,雖然它是非常低效的,也許有人可以改進:

遞減說,一,通過1.將該值存儲在b中。添加b和b並存儲在c中。 Beq c與a,如果它是真的,那麼b是a,aka srl的一半。唯一的問題是在某些情況下它將不得不循環數千次。仍然對其他想法開放。

+1

那麼,你的問題是什麼? – 2013-02-12 03:56:37

+0

這聽起來不像是一個實際問題。什麼處理器具有NAND和ADD,但沒有SRL? – 2013-02-12 04:55:43

+0

LC-3沒有右移。這是一個教育處理器。 – 2013-02-12 07:09:03

回答

0

爲了實現乘數,您需要邏輯左移,而不是右移。 左移簡單地由2乘以它可以通過自身添加值來實現:

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

右移不是那麼明顯,但。

+0

位串行累加乘法器使用右移(以獲取N個最高有效位)。這是一個有用的結構,例如定點算術。 OTOH在每一步執行右移都會比上一階段的一次移位效率低。 – 2013-02-12 07:56:52

+1

這正是我的觀點:在您正在使用的有限CPU中,只有通過循環和將每個位向右複製一次才能實現右移 - 這在大小和速度方面效率都非常低。 – johnfound 2013-02-12 08:13:06

1

右移可以通過兩個位掩碼來完成:out_bit=1,in_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。

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

下面是一個使用只有你有操作的代碼(你對於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; 
} 
+0

這幾乎是我的回答。 – 2013-02-13 07:13:53