Ответы CesarB и Pavel предоставили цитаты из AAPCS, но нерешенные вопросы остаются. Вызываемый сохраняет r9? Что насчет r12? Что насчет r14? Кроме того, ответы были очень общими и не были специфичными для набора инструментов arm-eabi, как было предложено. Вот практический подход, чтобы выяснить, какие регистры сохраняются вызываемыми, а какие нет.
Следующий код C содержит встроенный блок сборки, который претендует на изменение регистров r0-r12 и r14. Компилятор сгенерирует код для сохранения регистров, требуемых ABI.
void foo() {
asm volatile ( "nop" : : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14");
}
Использовать командную строку arm-eabi-gcc-4.7 -O2 -S -o - foo.c
и добавьте переключатели для вашей платформы (например, -mcpu=arm7tdmi
).
Команда выведет сгенерированный код сборки на STDOUT. Это может выглядеть примерно так:
foo:
stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
nop
ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
bx lr
Обратите внимание, что сгенерированный компилятором код сохраняет и восстанавливает r4-r11. Компилятор не сохраняет r0-r3, r12. То, что он восстанавливает r14 (псевдоним lr), является чисто случайным, так как я знаю из опыта, что код завершения может также загрузить сохраненный lr в r0 и затем выполнить «bx r0» вместо «bx lr». Либо добавив -mcpu=arm7tdmi -mno-thumb-interwork
, либо используя -mcpu=cortex-m4 -mthumb
, мы получим немного другой ассемблерный код, который выглядит следующим образом:
foo:
stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
nop
ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
Опять r4-r11 сохраняются и восстанавливаются. Но r14 (псевдоним lr) не восстанавливается.
Подведем итог:
- r0-r3 не сохраненный вызываемый
- r4-r11 сохранены вызываемым абонентом
- r12 (псевдоним ip) равен , а не сохранен вызываемый
- r13 (псевдоним sp) сохранен вызываемым абонентом
- r14 (псевдоним lr) равен , а не сохранено вызываемым абонентом
- r15 (псевдоним ПК) - это счетчик программы, для которого задано значение lr до вызова функции
Это относится, по крайней мере, к настройкам по умолчанию arm-eabi-gcc. Существуют ключи командной строки (в частности, ключ -mabi), которые могут влиять на результаты.