Неожиданное предупреждение об GNU ARM Assembler
Я пишу немного кода для Raspberry Pi и получаю неожиданное предупреждение от кросс-ассемблера ARM в Windows. Инструкции, вызывающие предупреждения были:
stmdb sp!,{r0-r14}^
а также
ldmia sp!,{r0-r14}^
Предупреждение:
Предупреждение: обратная запись в базовый регистр НЕПРЕДКАЗАНА
Я могу в некотором роде понять это, так как хотя модификатор '^' говорит процессору сохранять копии регистров в пользовательском режиме, он не знает, в каком режиме будет процессор, когда выполняется инструкция, и там не появляется быть способом сказать это. Я был немного более обеспокоен тем, чтобы получить такое же предупреждение для:
stmdb sp!,{r0-r9,sl,fp,ip,lr}^
а также:
ldmia sp!,{r0-r9,sl,fp,ip,lr}^
несмотря на то, что я явно не храню ЛЮБОЙ sp реестр.
Меня беспокоит то, что, хотя я 15 лет назад много писал на ассемблере, ARM-код для меня нов, и я могу что-то неправильно понять! Кроме того, если я могу безопасно игнорировать предупреждения, есть ли способ их подавления?
2 ответа
Термин "обратная запись" относится не к наличию или отсутствию SP
в списке регистров, но к !
символ, который означает, что инструкция должна обновить SP
значение с конца адреса области передачи. Значение базового регистра (SP) будет использоваться из текущего режима, а не из пользовательского режима, поэтому вы все равно можете загрузить или сохранить значение SP пользовательского режима в свой стек. Из ARM ARM B9.3.6 LDM (реестры пользователей):
В режиме PL1, отличном от системного режима, Load Multiple (пользовательские регистры) загружает несколько регистров пользовательского режима из последовательных ячеек памяти, используя адрес из базового регистра. Загруженные регистры не могут включать ПК. Процессор обычно считывает значение базового регистра, используя текущий режим, чтобы определить правильную версию регистра. Эта инструкция не может выполнить обратную запись в базовый регистр.
Диаграмма кодирования отражает это, указав бит 21 (W, обратная запись) как "(0)", что означает, что результат непредсказуем, если бит не равен 0.
Таким образом, решение просто не указывать !
и уменьшать или увеличивать SP вручную, если это необходимо.
В Справочном руководстве по архитектуре ARM говорится, что обратная запись не разрешена в LDM/SMT пользовательских регистров. Это разрешено в случае возврата исключения, где pc
находится в списке реестра.
LDM (исключение возврата)
LDM{<amode>}<c> <Rn>{!},<registers_with_pc>^
LDM (реестры пользователей)
LDM{<amode>}<c> <Rn>,<registers_without_pc>^