【问题标题】:16-bit word reversal using LC-3使用 LC-3 的 16 位字反转
【发布时间】:2012-10-28 21:08:18
【问题描述】:

我正在做分配工作,我将以二进制形式输入,并将其反向存储在另一个地址中。我正在使用一个 4 位字,直到我能够降低逻辑,然后在一切正常后将其扩展为一个 16 位字。

例如:1010100101001011 ==> 1101001010010101

到目前为止,这是我的方法:

字:1010 面具:0001 结果:0000

1) 1010 & 0001 - 和这个一起

 result is: 0000 

(我希望只能将最低有效位存储为结果中的最高有效位)

2) 1010 & 0010 - 增加了我的掩码,并与我的单词进行 AND 运算

结果是:0010

现在我将把位放在 2 的位置,并将其存储在我的结果寄存器中的 4 的位置。

这就是我在尝试提出逻辑以隔离一位然后将其存储在另一个位置时遇到的问题。

任何提示或建议将不胜感激。

【问题讨论】:

  • 您想对 16 位字进行完全位反转?您可能应该给出一个输入/输出示例以明确这一点,例如1011001011100011 => 1100011101001101,如果我理解正确?
  • 是的,你是对的。我将使用掩码在单词中移动,并使用 AND 函数查看孤立的位位置。我正在努力提出逻辑或想办法将其存储到我的结果寄存器中。我需要弄清楚如何从我的结果中发送一个特定位置的一个位.

标签: assembly bit-shift lc3


【解决方案1】:

假设您的意思是最小的 LC-3,它没有移位或除法指令:

  • ADD 可用于向左移动蒙版
  • ADD 可用于将结果左移
  • 您可以测试掩码与输入的 AND 是否为零
  • 使用测试结果将结果向左移动后添加 0 或 1

这里是 C 版本

uint16_t reverse16 (uint16_t input)
{
    uint16_t result = 0u;
    uint16_t mask = 1u;
    int i;

    for (i= 0; i < 16; i++)
    {
        result = result + result;
        if (0u != (input & mask))
        {
            result += 1u;
        }
        mask = mask + mask;
    }
    return result;
}

bithacks 网站有很多有趣的方法来解决这个问题和其他位级问题。

【讨论】:

    【解决方案2】:

    下面是 C 语言中 16 位字的位反​​转的简单(但易于理解)实现的逻辑:

    uint16_t w = 0xb2e3;         // our 16 bit word
    uint16_t mask0 = 0x0001;     // mask for LS bit
    uint16_t mask1 = 0x8000;     // mask for MS bit
    uint16_t shift = 15;         // distance between high and low bit positions
    
    for (int b = 0; b < 8; ++b)  // for each pair of low/high bits
    {
        uint16_t b0 = w & mask0; // get low bit
        uint16_t b1 = w & mask1; // get high bit
        w &= ~(mask0 | mask1);   // clear low/high bit in word
        b0 <<= shift;            // swap bit positions
        b1 >>= shift;
        w |= (b0 | b1);          // insert swapped bits back into word
        mask0 <<= 1;             // update masks for next pair of bits
        mask1 >>= 1;
        shift -= 2;              // update distance for next pair of bits 
    }
    
    printf("%#x\n", w);          // w should now contain 0xc74d
    

    测试代码:http://ideone.com/GgbzHw

    将上述循环转换为 LC3 应该相当简单,尽管综合 |&lt;&lt;&gt;&gt; 可能具有挑战性,因为指令集非常有限。

    【讨论】:

    • 非常感谢您抽出宝贵时间查看此内容并为我提供有用的信息。我一直在研究分支机构以及它们是如何工作的。如果我错了,请纠正我,但这就是我看到它的工作方式。例如: AND R3, R2, R1 (在此处插入新行) BRz #1 BRp #2 现在第一个 BR 语句会查看上一行的结果,如果为假,它将移至下一行?还是我必须拆分我的分支语句?
    • 这里有一个如何实现 for 循环的好例子:cs.colostate.edu/~fsieker/misc/CtoLC3.html - 它使用BRzp 作为循环测试分支。不过,对于仅像上面那样迭代 8 次的情况,您也许可以做一些更简单的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    • 2012-07-02
    • 1970-01-01
    • 2018-03-24
    • 1970-01-01
    • 2013-05-07
    相关资源
    最近更新 更多