Перейти к содержанию
    

EW430-4.21 Утекает стек

Всем доброго времени суток!

 

Просветите, пожалуйста.

 

Есть такая функция, которая чинно-благородно вызывает другую функцию, а та еще одну, а та еще одну - и рисует буковку.

 

void RenderStringDisplay(const char *pString, const CharInfo *pFont,
                        uint16 row, uint16 column, uint16 spacing,
                        uint16 address)
{
 uint16 x, y, initColumn;
 const CharInfo *pCharInfo;

 initColumn = column;

 // Loop through characters until NULL (0) found.
 while (*pString)
 {
   if (*pString == '\n') // Newline character?
   {
     column = initColumn;
     row += spacing;
   }
   else  // Not new line.
   {
     // Compute pointer to font information for current character.
     pCharInfo = &pFont[(unsigned char)*pString];

     // Compute origin of character bounding box.
     x = column + pCharInfo->offsetX;
     y = row - pCharInfo->offsetY - pCharInfo->height + 1;

     // Display the character
     DrawDisplayCharacter(pCharInfo, y, x, address);

     // Advance along line by appropriate horizontal spacing.
     column += pCharInfo->dwidth;
   }

   // Advance to next character.
   pString++;
 }
}

 

Все это прекрасно работает в отладчике, однако при возврате указатель стека уменьшается на 4. После нескольких вызовов уже начинает ругаться отладчик на переполнение стека. Впрочем, программа никуда не улетает и продолжает работать. Все прерывания запрещены.

Если выбрать опцию reduce stack usage, то это дело прекращается, SP при возврате возвращается точно назад. Что бы это значило?

При этом более простенькии функции с меньшей иерархией вложений стек отдают.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Непрятно разбираться в тексте, когда Вы игнорируете форматирование.

Вы не первый раз пишете, не новичок, "свой", разве трудно выделить код и нажать на иконку "Код" (самая левая). Это же неуважение к тем, кого Вы спрашиваете...

Вы можете включить генерацию ассемблерного листинга и найти, где Вас компилятор обманывает.

Конкретно по Вашему компилятору ничего не скажу, я использую старую версию 3.30, а вложений у меня очень много и прерывания разрешены, стек не утекает...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обманывает, конечно. Вот кусок call frame, каждый повторный вызов RenderStringDisplay смещает стек на 4, пока дело не дойдет до "приличных" функций, которые стек не отгрызают.

 

 

       FUNCALL main, RenderStringDisplay
       LOCFRAME CSTACK, 12, STACK
       FUNCALL main, RenderStringDisplay
       LOCFRAME CSTACK, 16, STACK
       FUNCALL main, RenderStringDisplay
       LOCFRAME CSTACK, 20, STACK
.............................................
       FUNCALL main, RenderStringDisplay
       LOCFRAME CSTACK, 32, STACK
       FUNCALL main, RenderCursor
       LOCFRAME CSTACK, 32, STACK
       FUNCALL main, WaitNonBusy
       LOCFRAME CSTACK, 32, STACK

 

Удивительно, но через какое-то время стек "вдруг" отдается.

 

 
       FUNCALL main, EnableRXInterrupts
       LOCFRAME CSTACK, 32, STACK
       FUNCALL main, RenderCursor
       LOCFRAME CSTACK, 8, STACK

 

Т.е. как бы все само излечивается. Однако факт переполнения стека отладчиком отмечается, что не есть хорошо. Вот такая странность. Ну и если reduce stack usage, что, вроде, ухудшает код, то этих фокусов не наблюдается.

 

        FUNCALL main, ClearDisplayImageBuffer
       LOCFRAME CSTACK, 8, STACK
       FUNCALL main, RenderStringDisplay
       LOCFRAME CSTACK, 12, STACK
       FUNCALL main, RenderStringDisplay
       LOCFRAME CSTACK, 12, STACK
.................................................... 

       FUNCALL main, RenderStringDisplay
       LOCFRAME CSTACK, 12, STACK
       FUNCALL main, RenderCursor
       LOCFRAME CSTACK, 8, STACK  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати, если в опциях проекта (я пишу для v3.30, в Ваше может быть несколько по иному, но смысл понятен), в категрии "Linker" во вкладке "Cmd Opt" поставить птичку "Use command line options" и вписать там -xmos, то в конце map-файла будет CALL GRAPH - там использование стека Вашей программой. Основываясь на этих данных Вы увеличиваете стек в категории "General Options" во вкладке "Stack/Heap".

 

Кстати, генерацию ассемблерного листинга включать в категории "C/C++ compiler" во вкладке "List" - птички "Ounput list file" и под ней "Assembler mnemonics" - позновательно иногда смотреть, что компилятор городит...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...