与非相邻寄存器的stm是否进行32位写操作?

时间:2013-07-08 08:56:18

标签: arm

我正在研究一段将编写一对32位寄存器的ARM代码,如下所示:

ldm r9!, {r0, r1}
sub r8, r8, #2
stm r10!, {r0, r1}

当r10输出指针是字对齐但不总是双字对齐时,上面的代码是否写入一个64位值?我对文档的阅读让我觉得在这种情况下会编写一个64位的值,但是我担心8字缓存行可能已经包含7个字的情况,然后这个代码执行64位写操作并将其分成一半高速缓存行末尾的dwords。

我在想,如果stm要做2个32位字写,那可能会避免这个问题。所以,我的问题是使用两个不相邻的寄存器强制stm写入2个字而不是dword?

ldm r9!, {r0, r2}
sub r8, r8, #2
stm r10!, {r0, r2}

以上代码与以下内容基本相同:

ldm r9!, {r0, r1}
sub r8, r8, #2
str r0, [r10], #4
str r1, [r10], #4

1 个答案:

答案 0 :(得分:2)

您正在写入或读取两个的寄存器编号与AMBA / AXI总线事务无关。唯一的连接是数据量。

这个问题有点模糊,我对所有不同的实现都知之甚少,但是如果你有一个64位的AXI总线而你的64位数据没有被写入64位对齐的地址(这是完全合法的例如,将2个寄存器写入地址0x1004)然后,对于未对齐地址(0x1004)上的第一项和对另一个(0x1008)的一个事务,它需要两个总线事务。假设您使用的是对齐的地址,那么它将执行一个独立于寄存器编号的64位事务,只要它们有两个。

缓存是另一个完全独立的主题。如果地址不是双字对齐的话,我相信你会得到两个单独的交易,这些交易将由缓存单独处理。理解L1缓存,如果你有一个在内核而不在AXI总线上,L2缓存(如果存在)位于核心和供应商AXI内存控制器之间的核心外部。因此L1行为和L2行为可能会有所不同,我不知道L1的内核接口是什么样的,以及它是否以及如何分解这些事务。我怀疑无论你使用什么样的处理器或型号,如果某些东西在内存系统或缓存逻辑中的某个点超过缓存行边界,它必须分解该事务并分别处理这两个缓存行。

从我所看到的,stm / ldm在必要时将单个指令转换为单独的总线事务。例如,写入0x1004的4寄存器变为3个单独的事务,在0x1004处为32位,在0x1008处为64位,在0x1010处为32位。自己这样做只会浪费指令获取周期,在这种情况下使用stm。