Поскольку ARM имеет ограниченную способность загружать непосредственные данные, утилиты, которые генерируют код для ARM, часто сопоставляют код и данные.Например, оператор типа
void myRoutine(void)
{
myVar1=0x12345678;
myVar2=0x87654321;
}
может выглядеть примерно так:
myRoutine:
ldr r0,=myVar1; Load the address of _myVar
ldr r1,=0x12345678
str r1,[r0]
ldr r0,=myVar1; Load the address of _myVar
ldr r1,=0x87654321
str r1,[r0]
bx lr
which would get translated into:
ldr r0,dat1
ldr r1,dat2
str r1,[r0]
ldr r0,dat3
ldr r1,dat4
str r1,[r0]
bx lr
... followed some time later by
dat1 dcd _myVar1
dat2 dcd 0x12345678
dat3 dcd _myVar2
dat4 dcd 0x12345678
or perhaps even something like:
mar r0,dat1
ldrm r0,[r1,r2,r3,r4]
str r2,[r1]
str r4,[r3]
bx lr
... followed some time later by
dat1 dcd _myVar1
dat2 dcd 0x12345678
dat3 dcd _myVar2
dat4 dcd 0x12345678
Обратите внимание, что _myVar и 0x12345678 могут быть помещены сразу после кода подпрограммы, в которой они появляются.;если вы попытаетесь определить длину подпрограммы, используя метку, которая следует за последней инструкцией, такая длина не будет включать в себя дополнительные данные.
Еще одна вещь, которую следует отметить с ARM, это то, что по историческим причинам коддля адресов часто задается младший значащий бит, хотя код фактически начинается с границ половинного слова.Таким образом, инструкция с адресом 0x12345679 будет занимать два или четыре байта, начиная с 0x12345678.Это может усложнить вычисление адреса для таких вещей, как memcpy.
Я бы порекомендовал написать небольшую подпрограмму на языке ассемблера, чтобы сделать то, что вам нужно.Это всего лишь несколько инструкций, вы можете точно знать, что делает код и какие адресные зависимости у него могут быть, и вам не придется беспокоиться о будущих версиях компилятора, которые изменят ваш код таким образом, чтобы что-то сломать [например, третийверсия приведенного выше кода не будет иметь проблем, даже если dat1
окажется на границе нечетного полуслова, поскольку инструкция L3 M3 может обрабатывать невыровненные чтения, но четвертая (немного более быстрая и более компактная) версия, использующая LDRM, в таком случае потерпит неудачу;даже если сегодняшняя версия компилятора использует четыре инструкции LDR, будущая версия может использовать LDRM].