【问题标题】:Implement bit operations only by ADD, SUB, MUL and DIV instructions仅通过 ADD、SUB、MUL 和 DIV 指令实现位操作
【发布时间】:2011-08-08 17:04:27
【问题描述】:

我正在编写一个编译器——只是为了好玩和提高我的技能。我想实现 C 语言的一个子集。问题是:我正在编译到名为 Sextium II 的理论上的 16 位 RISC 处理器的汇编器(我们曾经在大学教授汇编器)。

处理器只使用了 16 个命令,而且没有一个是位操作。我想实现 C 位运算符——然后是半精度浮点数——但我不知道如何仅使用 ADDSUBMULDIV 指令来实现位运算。位移很容易,它只是乘以或除以2^n,其中n 是位移长度。但是ANDORNOTXOR 呢?

编辑 需要明确的是:处理器仅使用 16 位有符号 U2 算法进行计算。

【问题讨论】:

  • 它会很慢,但是 x AND 1 是 x MOD 2,使用循环和移位,每次可以构造一个 16 位 AND。 1 位 x OR y 是 (x AND 1) || (y AND 1)(我假设您已经实现了这个),再次循环将为您提供 16 位版本。 XOR 和 NOT 类似。我确信这可以以更智能的方式完成,但这可以作为后备。

标签: assembly bitwise-operators


【解决方案1】:

如果您查看按位真值表进行添加,例如:

a b  c r
0 0  0 0
0 1  0 1
1 0  0 1
1 1  1 0

a 和 b 是输入操作数 r 是结果 c 是进位。

从位角度来看,加法是异或。但要将其用作通用异或,您需要执行 16 次加法操作,每个位一个,加上围绕屏蔽一个操作数和提取结果位的所有工作。

a b  c r
0 1  0 1
1 1  1 0

再次关注加法,但 b 操作数始终为 1,您将得到一个非函数。再次,需要掩蔽和移动。

你当然没有掩蔽和移位吧?

乘数将向左移动,乘以 2 是移动 1 乘以 4 移动 2,依此类推。同样,除法是右移。除以 4 是 2 的移位,除以 8 是 3 的移位,依此类推。您可以通过这种方式屏蔽单个位,除以 8 右移 3,然后乘以 0x8000 左移 15,然后除以 0x1000。这与使用 0x0008 的与操作相同吗?

如果可行,那么您可以说乘以 0x100,然后除以 0x100,这与与 0xFF00 的与运算相同。

它是有符号的乘法(和除法)还是无符号的?还是两者都有?

【讨论】:

  • 所有操作都是在 16 位有符号 U2 算术上进行的。
  • 当涉及符号位时,这可能会通过乘法和除法改变事情。例如,0x8000 * 0x7FFF 的无符号乘法是 0x3FFF8000,其中 0x8000 * 0x7FFF 的有符号乘法是 0xC0008000。您可能没有 16 位 * 16 位 = 32 位的结果,所以这两个可能看起来相同(实际上做了我希望他们做的事情),但是将 0x8000 除以 0x1000 得到 0x0008 无符号和 0xFFF8 有符号。
  • 谢谢。我认为会有一些技巧可以让事情变得更快,但显然没有。我会接受你的回答。
  • 听起来教学计算机需要更多指令,或者可能还有其他一些我们不知道的指令会有所帮助。例如,nor 或 nand 以及使用立即数的某种方式,您可以执行任何逻辑操作。
  • 不,只有 16 条指令,包括 NOP。
猜你喜欢
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多