Как "!" часть инструкции "LDM R1! {R2}" в архитектуре Armv6-M Кодирована? - PullRequest
1 голос
/ 24 февраля 2020

Когда я смотрю на официальные спецификации 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, но при рассмотрении общей структуры он, похоже, не складывается.

1 Ответ

3 голосов
/ 24 февраля 2020

Это задокументировано в документации по arm.

Изначально это выглядит странно, если вы привыкли к биту w, и поэтому вы можете проверить armv7-m, armv7-ar, конечно, go вернуться к исходному кронштейну

! 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}

Что также указано в psuedocode из документации на руку:

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

, так что это не кодируется как бит, как в более крупных инструкциях, это подразумевается на основе присутствия rn в списке регистров.

Теперь go вернуться к исходному рычагу

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, был также чем-то, чтобы поймать людей, делающих клоны.

...