0

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

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

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

在 ARM7TDMI 上,不可能只与像 0xFFFF 这样的常数进行与运算,因为它不适合立即值方案。

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

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

4

1 回答 1

3

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

4.15.5 加载半字(Little Endian)

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 引入/之前,仍然没有任何东西可以在单个指令中对寄存器进行零/符号扩展。UXTHSXTH

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

于 2016-11-30T23:11:07.197 回答