如何在ARM(ARM7TDMI)上最有效地获得低16位半字?



>假设我们在寄存器中有一个 32 位值:r0 = 0x12345678;任务是获得低半字部分,这是0x5678(或者取消高半字)。 就 C 代码而言,相当于:r0 = r0 & 0xFFFF;

限制:它需要在单个ARM7TDMI指令中完成,而无需使用其他寄存器。这是由于获得高半部分只是像LSR r0, r0, #16这样的正确转变。

到目前为止,我可以通过 2 个指令来完成:左移 + 右移,旋转 + 移位; 或者通过使用包含掩码0xFFFF和 AND-ing 的附加寄存器。

在ARM7TDMI上,不可能只使用 AND 像 0xFFFF 这样的常量,因为它不适合即时值方案。

此外,看起来现代 ARM-s 有"MOVT",它通过MOVT r0, #0来解决它,但ARM7TDMI没有!

我想相信没有MOVT是可能的,因为它是如此基本的东西。

如果有人暗示这可以在ARM7TDMI的一个指令中完成,他们就会让你上。所有早期 ARM 文档中的规范"零扩展半字"序列是两个班次,如 ARM7DI 数据表中的此示例所示:

4.15.5 加载半字(小端序)

LDR      Ra, [Rb,#2]          ; Get halfword to bits 15:0
MOV      Ra,Ra,LSL #16        ; move to top
MOV      Ra,Ra,LSR #16        ; and back to bottom
; use ASR to get sign extended version

7TDMI (ARMv4T) 在 7DI (ARMv3) 上添加的是半字加载和存储*,所以这个特定的例子在那之后消失了(它只是LDRH Ra, [Rb]),但加载当然只针对内存中已有的值;在 ARMv6 引入UXTH/SXTH之前,仍然没有什么可以在单个指令中对寄存器进行零/符号扩展。

* 在许多其他与这里无关的事情中。

相关内容

  • 没有找到相关文章

最新更新