Как упоминалось в ответе Питера Кордеса, в наборе команд AVR нет инструкции для загрузки 16-битного значения в регистровую пару. Но ...
, если невозможно загрузить 16-битное число в двух 8-битных регистрах
таким образом, может кто-нибудь может дать мне альтернативный вариант?
Для вашего удобства ассемблер обычно имеет возможность создавать макросы (обратите внимание на эту возможность, если вы планируете много программировать на ассемблере).
Синтаксис макроса зависит от набора инструментов. Для gnu as
я использую следующий макрос, который загружает 16-битное непосредственное значение в заданный и следующий регистр
.macro ldi_w reg:req, val:req
ldi \reg, lo8(\val)
ldi \reg + 1, hi8(\val)
.endm
So
ldi_w r16, 0xBEEF
загружает 0xEF
в r16
и 0xBE
в r17
.
Важное примечание: gnu as
позволяет использовать номера регистров (ldi 16, 0xC3
), а также имена регистров (ldi r16, 0xC3
). Приведенный выше макрос требует регистр числа , так что все мои источники ассемблера включают avr_reg_numbers.h
, который содержит определения, такие как
#ifdef r0
#undef r0
#endif
#define r0 0
С помощью этого макроса стиля пример ответа от Питера Кордеса можно переписать как
mov_w r30, r24 ; r30 ← r24, r31 ← r25
ld_w r24, Z
mov_w r30, r22
ld_w r18, Z
add_w r24, r18
p.s.0 My avr_as_macro.h
содержит много макросов, таких как lds_w
, sts_w
, push_w
,…, ror_w
и так далее. Большинство из них генерируются другими командами макроассемблера. Например, asr_w
, lsr_w
и ror_w
, сгенерированные
//---------------------------- right word shifts
// asr_w, lsr_w, ror_w
.irp cmd, asr, lsr, ror
.macro \cmd\()_w reg:req
\cmd \reg+1 $ ror \reg
.endm
.endr
p.s.1 Некоторые микросхемы AVR имеют инструкцию по сборке movw
, которая перемещает пару регистров за один цикл процессора, некоторые из них (старые или очень простые) не имеют такой команды. Поэтому я использую макрос mov_w
, который вызывает movw
или генерирует пару команд в зависимости от текущего уровня арки AVR.
//---------------------------------- word move
// movw exist in all new AVRs except __AVR_TINY__ (tiny4..10/20/40)
// Not exist in tiny26
// odd register numbers and overlapping are not supported
#ifdef __AVR_HAVE_MOVW__
.macro mov_w dst:req, src:req
movw \dst, \src
.endm
#else
.macro mov_w dst:req, src:req
mov \dst, \src $ mov \dst+1, \src+1
.endm
#endif