怎么 ”!” Armv6-M 架构编码中 "LDM R1! {R2}" 指令的一部分?

How is "!" part of "LDM R1! {R2}" instruction in Armv6-M Architecture Encoded?

当我查看 Arm 官方规格时,

! 
Causes the instruction to write a modified value back to <Rn> . If ! is omitted, the instruction does not change <Rn> in this way.

函数是这样解​​释的,然而ASL代码如下,

if ConditionPassed() then
  n = UInt(Rn); registers = '00000000':register_list;
  if BitCount(registers) < 1 then UNPREDICTABLE;
  wback = (registers<n> == '0');
  address = R[n];
  for i = 0 to 7
    if registers<i> == '1' then
      R[i] = MemA[address,4];
      address = address + 4;
if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);

因此,唯一合乎逻辑的做法是为此目的使用 wback,但当我检查一般结构时,它似乎并没有加起来。

arm文档中有记载。

如果你习惯了w位,一开始看起来很奇怪,所以可能会导致你检查armv7-m,armv7-ar,所以当然要回到原来的arm arm

! Causes base register writeback, and is not optional.

你也可以试一下,看看汇编程序是怎么想的

.cpu cortex-m0
.thumb
ldm r1,{r2}
ldm r1!,{r2}

arm-none-eabi-as so.s -o so.o
so.s: Assembler messages:
so.s:4: Warning: this instruction will write back the base register

第 4 行没有 !

Disassembly of section .text:

00000000 <.text>:
   0:   c904        ldmia   r1!, {r2}
   2:   c904        ldmia   r1!, {r2}

经过进一步检查,这不是文档中的错误

LDM <Rn>,<registers> <Rn> included in <registers>

所以测试一下

.cpu cortex-m0
.thumb
ldm r1,{r1}
ldm r1!,{r1}
so.s: Assembler messages:
so.s:5: Warning: this instruction will not write back the base register

第 5 行带有 !

Disassembly of section .text:

00000000 <.text>:
   0:   c902        ldmia   r1, {r1}
   2:   c902        ldmia   r1, {r1}

在 arm 文档的伪代码中也有说明:

if wback && registers<n> == ‘0’ then R[n] = R[n] + 4*BitCount(registers);

所以这不像在较大的指令中那样编码为位,这是基于寄存器列表中 rn 的存在暗示的。

现在回到原来的手臂手臂

Operand restrictions
If the base register <Rn> is specified in <registers>, the final value of <Rn> is the loaded value (not the written-back value).

所以即使在原文中也没有回写。如果你测试它,gnu 汇编器也会通过类似的消息知道这一点

.cpu arm7tdmi
.thumb
ldm r1,{r1}
ldm r1!,{r1}


arm-none-eabi-as so.s -o so.o
so.s: Assembler messages:
so.s:5: Warning: this instruction will not write back the base register

Disassembly of section .text:

00000000 <.text>:
   0:   c902        ldmia   r1, {r1}
   2:   c902        ldmia   r1, {r1}

这在 armv4 时代可能是有意为之,因为他们试图作为一家 IP 公司运营,并且出现了一些不可预测的结果,而其他类似的事情实际上是可以预测的,并且他们是如何测试你是否有偷了一个核心。如果原始 arm arm 文档中的这种写法也能吸引人们进行克隆,我不会感到惊讶。