在 thumb2 中设置寄存器的下半部分

Posted

技术标签:

【中文标题】在 thumb2 中设置寄存器的下半部分【英文标题】:setting lower half of a register in thumb2 【发布时间】:2014-07-04 03:48:51 【问题描述】:

我正在使用正版板,即 cortex-m3,使用 thumb2。我需要使用一堆 IO 端口,它们都有以 0x400E 开头的地址,例如 0x400E0E3C 等。我正在使用寄存器来存储这些地址。当我多次这样做时,我用地址 400E 加载寄存器的上半部分。如何在不影响上半部分的情况下使用立即 16 位值加载地址的下半部分。

这行得通 - movw r8, #400E movt r8, 0E3C

我只想执行第二条指令一次,但问题是每次我调用 movw 时,它都会将寄存器的上半部分重置为 0。我需要一条指令来加载寄存器的下半部分,而无需打扰了上半部分。

【问题讨论】:

没有单条ARM指令可以加载低16位而不影响前16位。可以循环16位,移动到上半部分,再循环16位,但这并不比使用2好16 位立即移动。另一种解决方案是将端口地址放在一个表中,用表地址加载一个寄存器,然后用寄存器+偏移地址加载。 movw+movt+ldr 可能会比 ldr+ldr 更快。 只是想到了一种更好更简单的方法,我可以在寄存器中填充 0x400E0000 并使用下半部分作为偏移量并加载内存位置。 P.S - 那没用,我的偏移量超出了范围。 你可以使用BFI,但是你需要一个备用的中间寄存器在插入它们之前加载立即数,而且每次加载仍然有两条指令,所以你最好使用MOVT . 是的,偏移量有效,因为我的地址的前 5 个十六进制数字相同,留下一个 12 位地址,适合。 【参考方案1】:

如果寄存器关闭,则使用索引。即str rn, [rB, #offset]偏移量相当generous +12bits。

加载/存储地址模式旨在有效地处理结构。您可以将寄存器库视为结构。 rB 是您的注册银行的基本索引;也许0x400e0e00

如果范围如此之大,您可能需要屏蔽基址rB 中的一些位(请参阅bicorr)。即,如果你有rB = 0x400e0000(访问0x400e0fff)并且你需要0x400ef010,那么,

orr rB, rB, #0xf000 # select high portion
ldr rn, [rB, #10]   # offset in high portion.
bic rB, rB, #0xf000 # back to low portion.

bfcbfi 也很有用,但如果您的算法允许,您可以只保留多个 rB 寄存器。

【讨论】:

以上是关于在 thumb2 中设置寄存器的下半部分的主要内容,如果未能解决你的问题,请参考以下文章

ARM NEON 内部函数将 D(64 位)寄存器转换为 Q(128 位)寄存器的低半部分,而上半部分未定义

如何在 vim 中设置默认寄存器?

STM32 DMA的使用总结

虚拟化技术基础原理

只有 EAX 的低半部分归零? (MASM 使用 .486 / .model flat,stdcall)

点击CollectionView Cell的下半部分时推动ViewController