ldr r0, =21475234
Это ярлык, почти псевдокод. Различные кронштейны рычагов имеют тенденцию поддерживать его.
Вероятно, предполагается использовать как этот
ldr r0,=hello
ldr r1,[r0]
...
in some other file perhaps
.globl hello
hello:
.word 0x1234
В основном это означает, что загрузить адрес вещи после знака равенства.
ldr r0,hello
...
hello:
.word 0x1234
говорит, что загружает значение данных на ярлыке hello в r0.
В C именно это
//ldr r0,=hello
unsigned int r0 = (unsigned int)&hello;
//ldr r0,hello
unsigned int r0 = hello;
Потому что рука по большей части набор фиксированной инструкции длины, где инструкции размер или меньше регистров вы не можете загрузить любой немедленным вы хотите, чтобы при использовании номер для ваших деталей адрес, а не этикетки
ldr r0,=0x12345678
, который кодируется как
ldr r0,temp000
...
temp000: .word 0x12345678
Загрузите значение 0x12345678 в r0. Ассемблеру необходимо найти место, достаточно близко к ldr, но с пути исполнения, чтобы разместить это слово данных, и иногда вы получите сообщение об ошибке, которое не может найти место.
Так
ldr r0, =21475234
Загружает значение 21475234 в r0.
Этот пуск push {r4, r5, lr} сохраняет r4, r5 и регистр возврата lr в стеке. Обычно используемое соглашение о вызове говорит, что для руки вы можете уничтожить r0-r3, но вы должны сохранить другие регистры (есть два или два исключения), поэтому для использования r4 мы должны его сохранить. Я предполагаю, что это был скомпилированный код, не написанный вручную, и/или он вызван из скомпилированного кода?
так что теперь мы можем использовать r4, это копирует значение 21475234 в r4, r0 и r4 держать то же самое для теперь мов r4, r0 , когда вы кладете [скобки] вокруг регистра, в основном регистре косвенную адресация, вместо желания содержимое этого регистра, содержимое этого регистра адреса для содержимого, которое необходимо, так это говорит прочитать значение по адресу 21475234 и сохранить это значение в r5
ldr r5, [r4]
вы убрали код здесь для публикации этого вопроса?
это говорит прочитать значение по адресу 21475234 + 4 и кроме того, что в r0
ldr r0, [r4, #4]
Когда непосредственное значение в скобках, что означает добавить, что в регистр и использовать этот адрес для чтения с адреса в регистр r4 плюс 4.
ldr r0, [r4, #4]
чтения с адреса, полученного путем добавления r4 + r5
ldr r0, [r4, r5]
это совсем другое, это говорит, прочитанный с адреса в r4, поместите значение в r0 THEN ADD 4 TO R4.
ldr r0, [r4], #4
Это будет похоже на код C
unsigned int r0 = *r4++;
Л.Р. является регистр ссылки r14, рс счетчика программы r15, когда вы меняете r15 это эффективно филиал. Нажатие lr сохраняло адрес возврата, когда вызывалась функция (процедура, proc) таким образом, что вы можете вернуться к запущенному коду сразу после вызова функции. Для этого вам необходимо поменять счетчик программ на адрес, который находится сразу после вызова (bl = ветвь связи, которая в основном является вызовом функции на какой-либо адрес). Так что в руке вы можете нажать Ьги и поп-ПК, так что
pop {r4,r5,pc}
является дополнением к толчку, он восстанавливает r4 и r5 к значениям, которые были там, когда функция была введена, а затем выталкивает возвращение адрес в счетчик программ, чтобы программа перешла на этот адрес.
traverse - это метка или название процедуры (функции), процедура краткая для процедуры. Несомненно, сборщик-мнемоник, который более специализирован, чем просто объявление метки. Ярлык должен работать нормально, но вы можете получить дополнительную помощь от ассемблера, если вы это сделаете. (Я никогда не нашел причины делать это за 20 лет работы над сборкой ежедневно, но, возможно, у других есть).
bl traverse, это рекурсивный вызов. Не знаете, как вы выходите из этого, вы опубликовали весь код?
Это рекурсивная функция, которая не завершается. Здесь что-то сломалось. –