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

时间:2016-11-30 22:06:32

标签: assembly arm arm7

假设我们在寄存器中有一个32位值:r0 = 0x12345678;任务是获得低半字部分,即0x5678(或者使高半字无效)。 就C代码来说,它相当于:r0 = r0 & 0xFFFF;

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

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

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

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

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

1 个答案:

答案 0 :(得分:3)

如果有人暗示这可以在ARM7TDMI的一条指令中完成,那么他们就让你开心。所有早期ARM文档中规范的“零延伸半字”序列是两个班次,如本例中的mediaStatus()

  

4.15.5加载半字(Little Endian)

LDRH Ra, [Rb]

7TDMI(ARMv4T)在7DI(ARMv3)上添加的是半字加载和存储 * ,所以此特定示例在此之后消失(它仅仅是{{ 1}}),但加载当然只适用于已经在内存中的值;在ARMv6引入UXTH / SXTH之前,仍然没有任何内容可以对寄存器进行零/符号扩展。

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