二进制右移,仅给出加法

问题描述 投票:0回答:4

我正在开发一个项目,我正在读取内存位置并需要以 ASCII 输出它们的十六进制值。

该语言为我提供了 16 位字长,因此我需要进行除法以一次抓取一个半字节以转换为十六进制。不幸的是,该语言仅提供数学/逻辑函数的“与”、“或”、“非”和“加”。

我想我可以通过左移并测试负标志以在移位后在末尾添加 1 来创建所需的效果,但我认为必须有更好的方法来做到这一点。

任何见解将不胜感激。

assembly binary bit-manipulation bit-shift lc3
4个回答
1
投票

使用

AND
,您可以将除最后一个有效半字节之外的所有位设置为零:

0101010111010101
0000000000001111 AND
----------------
0000000000000101

通过向右移动整个内容,您可以读取下一个半字节:

0101010111010101 SHR 4
----------------
    010101011101
0000000000001111 AND
----------------
0000000000001101

这对你有用吗?


0
投票

你有带carry的add吗?不是对负数进行测试,而是在末尾添加该位,并添加一个带进位的零以将其放回右侧。 并没有真正节省太多。 到目前为止我想不出另一个解决方案,左移,测试一下,如果设置添加 1 到某个东西并移动那个东西:

uint a,b,i;

b=0;
for(i=0;i<4;i++)
{
   b=b+b;
   if(a&0x8000) b+=1;
   a=a+a;
}

如果上面的 uint 是 16 位,那么上面的代码将右移 12 位。a 将在创建 b 的过程中被销毁,如所写。


0
投票

您可以反向尝试:您可以使用蛮力,而不是尝试实现右移。这是最高半字节的示例:

unsigned rez, tmp;
for (rez = 0, tmp = some_word & 0x0FFF; tmp != some_word; rez++, tmp += 0x1000);

0
投票

所以我原来使用的方法有效。我还想出了另一个,以防有人再次遇到这个问题。

我构建了一个子例程,一次评估 4 位并根据评估创建一个数字,对于某些 C 风格的伪代码,它看起来像这样:

16bitSignedInt bin; //binary being analyzed
int value; //number being built

for (int i = 0; i < 4; i++) // while 0-3, for each nibble of the 16 bits
{
   if (bin.bit15 = 1)
      value += 8; // dominate bit in nibble

   bin <<= 1; // left shift 1

   if (bin.bit15 = 1)
      value += 4; // 2nd bit in nibble

   bin <<= 1; // left shift 1

   if (bin.bit15 = 1)
      value += 2; // 3rd bit in nibble

   bin <<= 1; // left shift 1

   if (bin.bit15 = 1)
      value += 1; // last bit in nibble

   bin <<= 1; // left shift 1

   //do work with value
}

简单,但有效。

© www.soinside.com 2019 - 2024. All rights reserved.