Что может быть причиной для использования инструкции ADDS вместо инструкции ADD в сборке ARM? - PullRequest
0 голосов
/ 29 января 2019

Мои заметки о курсе всегда используют ADDS и SUBS в своих фрагментах кода ARM вместо ADD и SUB, как я и ожидал.Вот один из таких примеров, например:

__asm void my_capitalize(char *str)
{
cap_loop
  LDRB r1, [r0]   // Load byte into r1 from memory pointed to by r0 (str pointer)
  CMP r1, #'a'-1  // compare it with the character before 'a'
  BLS cap_skip    // If byte is lower or same, then skip this byte
  CMP r1, #'z'    // Compare it with the 'z' character
  BHI cap_skip    // If it is higher, then skip this byte
  SUBS r1,#32     // Else subtract out difference to capitalize it
  STRB r1, [r0]   // Store the capitalized byte back in memory

cap_skip
  ADDS r0, r0, #1 // Increment str pointer
  CMP r1, #0      // Was the byte 0?
  BNE cap_loop    // If not, repeat the loop
  BX lr           // Else return from subroutine
}

Этот простой код, например, преобразует все строчные английские буквы в строке в прописные.В этом коде я не понимаю, почему они не используют команды ADD и SUB вместо используемых в настоящее время ADDS и SUBS.Команда ADDS и SUBS afaik обновляет флаги APSR NZCV для дальнейшего использования.Однако, как видно из приведенного выше фрагмента, обновленные значения не используются.Есть ли какая-либо другая утилита этой команды?

Ответы [ 2 ]

0 голосов
/ 29 января 2019

ADD без обновления флага недоступно для некоторых кортекс-мс.Если вы посмотрите документацию arm для набора инструкций (это всегда хорошая идея при использовании языка ассемблера) для случаев общего назначения, которые недоступны до расширения thumb2 на armv7-m (cortex-m3, cortex-m4, cortex-m7).В cortex-m0 и cortex-m0 +, а также в целом широком коде совместимости (который будет использовать armv4t или armv6-m) нет опции добавления без флагов.Так что, возможно, именно поэтому.

Другая причина может заключаться в том, чтобы получить 16-битную инструкцию, а не 32-ю, но это скользкий уклон, поскольку она еще больше распространяется на ассемблеры и их синтаксис (синтаксис определяетсяассемблер, программа, которая обрабатывает язык ассемблера, а не цель).например, не синтаксический унифицированный газ:

.thumb
add r1,r2,r3

Disassembly of section .text:

00000000 <.text>:
   0:   18d1        adds    r1, r2, r3

дизассемблер знает реальность, но ассемблер не знает:

so.s: Assembler messages:
so.s:2: Error: instruction not supported in Thumb16 mode -- `adds r1,r2,r3'

, но

.syntax unified
.thumb
adds r1,r2,r3
add r1,r2,r3


Disassembly of section .text:

00000000 <.text>:
   0:   18d1        adds    r1, r2, r3
   2:   eb02 0103   add.w   r1, r2, r3

, поэтому не скользко в этом случае, но с унифицированным синтаксисом вы начинаете входить в синтаксис типа blahw, blah.w, blah, type и вынуждены возвращаться, чтобы проверить, генерируются ли нужные вам инструкции.non-unified также имеет свои собственные игры, и, конечно, все это зависит от ассемблера.

Я подозреваю, что они либо выбирали единственный выбор, либо использовали меньшую и более совместимую инструкцию, особенно еслиэто был класс или текст, чем больше он совместим, тем лучше.

0 голосов
/ 29 января 2019

Арифметические инструкции (ADD, SUB и т. Д.) Не изменяют флаг состояния, в отличие от команд сравнения (CMP, TEQ), которые по умолчанию обновляют флаги состояния.Однако добавление S к арифметическим инструкциям (ADDS, SUBS и т. Д.) Обновит флаги условий в соответствии с результатом операции.Это единственная точка использования S для арифметических инструкций, поэтому, если cf не будет проверяться, нет смысла использовать ADDS вместо ADD.


Есть еще коды для добавления к инструкции ( ссылка ), для достижения различных целей, таких как CC (условный флаг C = 0), следовательно:

ADDCC: выполнить операцию, если бит состояния переноса установлен на 0.

ADDCCS: выполнить операцию, если бит состояния переноса установлен на 0, а затем обновить флаги состояния (если C = 1флаги состояния не перезаписываются).


С точки зрения циклов, нет разницы между обновлением условных флагов или нет.Рассматривая ARMv6-M в качестве примера, ADDS и ADD займут 1 цикл.


Отмена использования ADD может показаться ленивым выбором, посколькуADD довольно полезно для некоторых случаев.Далее рассмотрим следующие примеры:

  SUBS r0, r0, #1
  ADDS r0, r0, #2
  BNE go_wherever

и

  SUBS r0, r0, #1
  ADD r0, r0, #2
  BNE go_wherever

могут приводить к разным поведениям.


Как указал old_timer, UAL становится весьма актуальным в этой теме.Говоря об унифицированном языке, предпочтительный синтаксис - ADDS вместо ADD ( link ).Таким образом, код OP абсолютно идеален (даже рекомендуется), если целью является сборка для Thumb и / или ARM (с использованием UAL).

...