внутри голой функции - как сделать простое назначение - PullRequest
0 голосов
/ 19 января 2019

Это начало функции, которая уже существует и работает; закомментированная строка - мое дополнение, и ее цель - переключить булавку.

inline __attribute__((naked)) 
void CScheduler::SwapToThread(void* pNew, void* pPrev)
{   
    //*(volatile DWORD*)0x400FF08C = (1 << 14);
    if (pPrev != NULL)
    {
        if (pPrev == this) // Special case to save scheduler stack on startup
        {
            asm("mov lr,%0"::"p"(&CScheduler_Run_Exit));     // load r1 with schedulers End thread
            asm("orr lr, 1");

Когда я раскомментирую свое дополнение, исполняется мой обработчик сбоев. Я понимаю, что это как-то связано с функцией naked, но я не понимаю, почему простое назначение вызывает проблему.

Два вопроса:

  1. Почему эта строка вызывает серьезную ошибку?
  2. Как я могу выполнить это назначение внутри этой функции?

1 Ответ

0 голосов
/ 19 января 2019

Нам повезло, что ваша предыдущая версия функции работала без сбоев.

Единственное, что можно безопасно поместить в функцию naked, - это чистый оператор Basic Asm.https://gcc.gnu.org/onlinedocs/gcc/ARM-Function-Attributes.html. Вы можете разделить его на несколько операторов Basic Asm вместо asm("insn \n\t" / "insn2 \n\t" / ...);, но вы должны написать всю функцию в asm самостоятельно.

Хотя использование расширенного asm или смеси базового кода asm и C может показаться работоспособным, от него нельзя зависеть, чтобы оно работало надежно и не поддерживается.

Если вы хотите запустить код C ++ из«голая» функция, вы можете call обычную функцию (или bl в ARM, jal в MIPS и т. д.), следуя стандартному соглашению о вызовах.


Что касается конкретногопричина в этом случае?Может быть, создание этого адреса в регистре наступило на функцию args, что привело к неправильной ветке?Проверьте сгенерированный asm, если хотите, но он на 100% не поддерживается.

Или, может быть, он использовал больше регистров, и, поскольку он naked не правильно сохранил / восстановил регистры, сохраняемые при вызове?Я не смотрел на генератор кода для обнаженных функций.

Вы уверены, что эта функция должна быть naked?Я думаю, это потому, что вы манипулируете lr, чтобы вернуться в новый контекст.

Если вы не хотите просто писать больше логики в asm, возможно, чтобы вызывающая функция этой функции выполняла больше работы (и, возможно, передавала указатель)и / или логические аргументы, говорящие ему более просто о том, что ему нужно делать, поэтому ваши входные данные уже находятся в регистрах, и вам не нужен доступ к глобальным переменным).

...