2013-04-01 12 views
9

W programie C, który nie korzysta z rekursji, teoretycznie powinno być możliwe obliczenie maksymalnego/najgorszego rozmiaru stosu potrzebnego do wywołania danej funkcji i wszystkiego, co jest potrzebne. to wywołuje. Czy są jakieś darmowe narzędzia open source, które mogą to zrobić, albo z kodu źródłowego, albo ze skompilowanych plików ELF?Maksymalny rozmiar stosu potrzebny dla programu C na MSP430

Czy istnieje sposób na wyodrębnienie rozmiaru ramki stosu funkcji z pliku ELF, aby można było spróbować go rozwiązać ręcznie?

Kompiluję dla MSP430 używając MSPGCC 3.2.3 (wiem, że to stara wersja, ale muszę w tym przypadku użyć). Miejsce na stos do przydzielenia jest ustawione w kodzie źródłowym i powinno być tak małe, jak to tylko możliwe, aby reszta pamięci mogła być wykorzystana do innych celów. Czytałem, że musisz wziąć pod uwagę przestrzeń stosu używaną przez przerwań, ale system, którego używam, już to uwzględnia - staram się ustalić, ile dodatkowego miejsca należy dodać. Ponadto, czytałem, że wskaźniki funkcji utrudniają to. W tych kilku miejscach, w których są używane wskaźniki funkcji, wiem, które funkcje mogą wywoływać, więc można wziąć pod uwagę te przypadki ręcznie, jeśli przestrzeń stosu potrzebna dla wywoływanych funkcji i funkcji wywołujących była znana.

Analiza statyczna wydaje się bardziej niezawodną opcją niż malowanie w stosie w środowisku wykonawczym, ale praca w środowisku wykonawczym jest opcją, jeśli nie ma sposobu, aby zrobić to statycznie.

Edit:

znalazłem GCC -fstack-usage flagę, która oszczędza rozmiar ramki dla każdej funkcji, ponieważ jest skompilowany. Niestety, MSPGCC nie obsługuje tego. Ale może być przydatny dla każdego, kto próbuje zrobić coś podobnego na innej platformie.

+0

Czy to naprawdę jest sposób na rozwiązanie problemu? Zawsze byłem dość hojny przy stosie i chroniłem go kanarkami stosu, aby zobaczyć, że jest nienaruszony. Głównym problemem związanym z tym podejściem jest to, że może to powodować problemy później. Takich jak wtedy, gdy potrzebujesz większej pamięci programu, powiedzmy, 24-bitowy komputer zamiast 16 (teraz tylko ogólne 8-bitowe doświadczenie), lub potrzebujesz tylko kilku dodatkowych funkcji najlepiej zrealizowanych z dodatkowymi warstwami połączeń. Wtedy precyzyjnie ustawiony stos może naprawdę cię odzyskać. Oczywiście, jeśli wyciskasz ostatnie bity, to OK, ale myślę, że to powinno być ostatnie. – Jubatian

+0

"Czy są dostępne darmowe narzędzia o otwartym kodzie źródłowym". Dostępna jest darmowa wersja (nie otwartego pliku) IAR IDE (przez 30 dni lub limit kodu 4K), w której opcja listy linkerów generuje zużycie stosu dla aplikacji. Nawet jeśli używasz GCC, do uzyskania szczegółowych informacji, takich jak Rozmiar stosu (suma i dla każdej funkcji), rozmiar kodu (suma i dla każdej funkcji) i inne szczegóły, takie jak rozmieszczenie pamięci i zmienne adresy i rozmiary itp., Możesz użyć IAR Wbudowany pulpit. – Harikrishnan

+0

możliwy duplikat [Sprawdzanie użycia stosu podczas kompilacji] (http://stackoverflow.com/questions/126036/checking-stack-usage-at-compile-time) – shodanex

Odpowiedz

0

Interesujące pytanie.

Oczekuję, że informacje te będą statycznie dostępne w danych debugowania zawartych w kompilacjach debugowania.

miałem krótkie spojrzenie na standardzie DWARF i robi określić dwa atrybuty funkcji zwanych DW_AT_frame_base i DW_AT_static_link które mogą być wykorzystywane do „oblicza podstawę rama odpowiedniej instancji podprogramu że natychmiast zamyka podprogram lub punkt wejścia ".

+0

Dzięki. Nie jestem pewien, jakie one są przydatne, ale natrafiłem na "informacje o ramkach połączeń" w specyfikacji DWARF, która wygląda na to, że może zawierać więcej informacji. Teraz potrzebuję tylko GCC do wygenerowania sekcji .debug_frame - '-gdwarf-2 -g3' tego nie robi. – cjc

0

Myślę, że jedyne, do którego należy się udać, to analiza statyczna. Musisz obliczyć miejsce dla wszystkich niestatycznych zmiennych lokalnych, które będą głównie wskaźnikami, ale wskaźniki, które i tak będą przechowywane w stosie, musisz także zarezerwować miejsce na bieżący adres w ramach caller, ponieważ będzie przechowywany przez kompilator na stosie, więc kontrola może zostać zwrócona do wywołującego po powrocie funkcji, a także, potrzebujesz miejsca na wszystkie parametry funkcji. Na tej podstawie, jeśli dysponujesz narzędziem umożliwiającym zliczanie wszystkich parametrów, zmiennych automatycznych i obliczanie ich rozmiaru, powinieneś być w stanie obliczyć minimalny rozmiar stosu, który będziesz potrzebować. Należy pamiętać, że kompilator może również próbować wyrównać wartości na stosie dla konkretnej architektury, co może sprawić, że wymagania dotyczące przestrzeni stosu będą trochę większe, niż można oczekiwać od tego obliczenia.

0

Niektóre wbudowane IDE mogą podawać informacje na temat używania pakietu w środowisku wykonawczym Wiem, że wspierany przez IAR eembedded workbench jest obsługiwany.

Pamiętaj, że musisz wziąć pod uwagę, że przerwania występują asynchronicznie, więc weź największy scenariusz użycia stosu i dodaj do niego kontekst przerwań. Jeśli obsługiwane są przerwań zagnieżdżonych, podobnie jak w procesorach ARM, należy wziąć to również pod uwagę.

1

Podczas gdy analiza statyczna jest najlepszą metodą określania maksymalnego użycia stosu, może być konieczne zastosowanie metody eksperymentalnej. Ta metoda nie może zagwarantować ci absolutnego maksimum, ale może dostarczyć ci bardzo dobry pomysł na wykorzystanie twojego stosu.

Możesz sprawdzić swój skrypt linkera, aby uzyskać lokalizację __STACK_END i __STACK_SIZE. Możesz ich użyć, aby wypełnić przestrzeń stosu łatwo rozpoznawalnym wzorcem, takim jak 0xDEAD lub 0xAA55. Przeprowadź swój kod przez test torturowania, aby upewnić się, że wygenerowano jak najwięcej przerwań.

Po zakończeniu testu można sprawdzić przestrzeń stosu, aby sprawdzić, jaka część stosu została nadpisana.

+0

Można nawet zadeklarować je jako zewnętrzne. 'extern char __STACK_END;' '& __ STACK_END' będzie adresem ostatniego bajtu w stosie – Michael

Powiązane problemy