繁体   English   中英

通过移位、反转和加 +/- 1 构造十六进制数

[英]Constructing a hex number by shifting, inverting and adding +/- 1

我正在尝试将数字0xFD00保存在寄存器中(MIC-1 架构)。 有寄存器:

  • 0
  • +1
  • -1
  • AMASK:0x0FFF
  • 面具:0x00FF

我可以进行左移、右移和反转。 也可以添加 SMASK + SMASK 或 AMASK + (-1) 等值。 我可以通过逆(AMASK)获得 0xF000,但我不确定如何在没有太多步骤的情况下获得 0xFD00。

0xFD 是0b11111101 所以它有一堆连续的位,还有一个保持设置位。 所以一种简单的方法是

  • 以全 1 开头( -1~00 - 1
  • 左移 2 得到...11111100
  • 加 1 得到...11111101 (0x...FD)
  • 移到寄存器的顶部,移入低 0 并移出高 1,将0xFD留在顶部,有 8 个低零。

我不知道 MIC-1,但从你的描述看来它可以完成这些步骤。 如果一次只能移位 1 个 position,则总共需要 2 + 8 个移位指令。 可能还有其他方法可以更有效地构造这个常数,也许是我没有想到的东西,或者机器有一些能力。


利用 AMASK / SMASK 和 add / sub carry-propagation 的方式可以分别翻转 1 / 0 位的序列,以及 Aki 观察到~0xfd00 = 0x02ff ,我们可以执行以下操作:

initial AMASK = 0x00FF

AMASK += 1     (0x0100)
AMASK += AMASK (0x0200)  (left shift)
AMASK += SMASM (0x02FF)
NOT AMASK      (0xFD00)

请参阅https://catonmat.net/low-level-bit-hacks以了解您可以使用按位运算处理的各种恶作剧。 (尽管其中许多还需要 AND、OR 或 XOR。例如,通过x &= (x-1)清除最低设置位)


(相关:动态生成向量常量的最佳指令序列是什么?对于 x86 SIMD 向量:类似的问题,您可以在不从 memory 加载的情况下廉价地动态生成-1 ,并通过各种其他指令(如左移)输入它, (SSSE3)绝对值。但只值得为短序列做,否则只需从 memory 或 mov-immediate 加载到 integer regsiters 和movd xmm0, eax


十六进制只是在文本中表示数字的一种方式,例如 ASCII。 您可以将其称为序列化格式。

0xFD00只是另一种写入64768 (基数 10)或0b1111110100000000 (基数 2)的方式。 因此,您只是在移位和 inc/dec 的寄存器中构造一个数字 假设您的位移乘以/除以 2,而不是 10 或 16,这些是二进制操作,所以这是一个二进制数。 以像十六进制这样的紧凑格式表示所需的二进制数很方便,但在任何时候你都不需要十六进制,就像一串base-16 ASCII数字。

当您在寄存器中构造它时,它不是“十六进制数”,它只是一个数字。 如果有的话,它是二进制的。

0xFD00 的倒数 == 0b00000010 11111111 = 0x02ff

这可以通过 SMASK = 0x00FF * 3 + 2 或简单地使用 SMASK | 来实现。 (1 << 9),如果可用的话。

a = smask
b = smask << 1
a = a + b
a++
a++
return ~a

假设左移只是删除移出 16 位字的位:

t = ~SMASK    // 0xff00
return t + (t << 1)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM