|
|
  |
скрипт + gcc |
|
|
|
Jul 17 2009, 10:48
|
Частый гость
 
Группа: Участник
Сообщений: 104
Регистрация: 30-06-05
Из: С-Петербург
Пользователь №: 6 406

|
Цитата Смысл задуманного как раз в том чтобы освободить программиста от такого "счастья". От какого счастья Вы собрались освободить программиста таким способом?
--------------------
Hemos Pasado
|
|
|
|
|
Jul 17 2009, 10:59
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(smac @ Jul 17 2009, 14:19)  Если ф-я вызывается в цикле, если условие цикла зависит от железа ? Условия проверяться не будут, т.к кол-во комбинаций=n! очень велико уже при n=10, где n-кол-во условных операторов. Просто будет собираться статистика вызовов каждой функции, анализироваться есть ли вложенные функции.? По поводу циклов не понял, уточните, а лучше пример в коде. На счет железа, это если что то из порта приходит? В любом случае условия не проверяются см. выше. Цитата(Troll @ Jul 17 2009, 14:48)  От какого счастья Вы собрались освободить программиста таким способом? Освободить от "счастья" самому руками задавать стек путем написания скрипта, результаты работы которого передавать в проект до компиляции. P.S на связь выду только в Пндк.
|
|
|
|
|
Jul 17 2009, 12:52
|

Местный
  
Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091

|
Прошу прощения за молчание - я в отпуске, сюда заглядываю редко... Цитата(antiwin @ Jul 14 2009, 16:08)  Да в общем случае ненадо, можно ли найти данные(в файлах lst, map...) или где еще позволяющие расчитать вершину стека.? Можно смотреть сгенерированный компилятором ассемблерный текст, находить все манипуляции со стеком и считать. А потом пересчитывать при каждой модификации исходника... Муторно очень. Я такой "подвиг" совершаю только для коротеньких фрагментов (типа обработчика прерывания), изначально целиком написанных на ассемблере... Есть,например, такой метод: изначально весь стек заполняется какой-то константой, затем процесс запускается на выполнение (в симуляторе или живом устройстве), причем по возможности стараются прогнать выполнение по всем возможным веткам программы. После прогона смотрят, какая часть области стека осталась заполнена константой, а какая была использована (переписана). По результатам такого измерения корректируется размер выделенной под стек области памяти (с некоторым запасом). Цитата(antiwin @ Jul 16 2009, 13:42)  К стати, пытался найти описание malloc и других встроенных функций, но кроме определения не нашел. Где же они все таки описанны.? Цитата(antiwin @ Jul 17 2009, 14:05)  Под описанием я имел ввиду не описание в человеческом смысле, а в рамках С99, т.е тело функции. А в предложенных ссылках (за них спасибо) описанние именно в первом смысле. В терминах C99 есть понятия "объявление" (declaration), для функций также называемое прототипом, и "определение" (definition), где содержится собственно код тела функции. Прототип malloc находится в <stdlib.h>, а где находится ее определение, зависит от используемой Вами библиотеки.
--------------------
Всего наилучшего, Alex Mogilnikov
|
|
|
|
|
Jul 17 2009, 13:58
|
Частый гость
 
Группа: Участник
Сообщений: 104
Регистрация: 30-06-05
Из: С-Петербург
Пользователь №: 6 406

|
Цитата(antiwin @ Jul 17 2009, 17:59)  Освободить от "счастья" самому руками задавать стек путем написания скрипта, результаты работы которого передавать в проект до компиляции. Так для этого надо считать не указатели, а операции со стеком. постом выше, рассказали как определить размер стека и почему этого не надо делать при каждой компиляции. А на этапе отладки всегда можно посмотреть вершину стека и определить похерил ее кто-нибудь или нет.
--------------------
Hemos Pasado
|
|
|
|
|
Jul 17 2009, 15:33
|
Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003

|
Цитата(antiwin @ Jul 17 2009, 14:59)  Условия проверяться не будут, т.к кол-во комбинаций=n! очень велико уже при n=10, где n-кол-во условных операторов. Просто будет собираться статистика вызовов каждой функции, анализироваться есть ли вложенные функции.? По поводу циклов не понял, уточните, а лучше пример в коде. На счет железа, это если что то из порта приходит? В любом случае условия не проверяются см. выше. Пример конечно гипотетический, но Код int i; char *p; for (i=0; i<MAX; i++) //запускаем цикл по i (ну допустим количество опросов датчика или т. п.) if (SOME_PIN_IS_LOW&&(i&0x01)) // если нужная нога - 0 и номер опроса нечетный, то просим памяти p= (char*)malloc(SOME_MEMORY); С одной стороны, если функция вызывается и возвращается обратно, то стек она освободит (допустим мы заведомо знаем сколько стека она отожрет), но в данном примере число вызовов malloc() и соответсвенно количество требуемой памяти будет определяться временем сохранения истинных условий, естественно количество вызовов может варьировться от 0 до MAX/2 раз. Определить хватит ли памяти можно только прогоном программы иначе никак. Сомневаюсь что Ваш анализатор справится с задачей "просто заглянув исходник". Конечно данный пример не показывает как можно "перелезть" через вершину стека, однако я думаю что он показателен в смысле того что нельзя заранее определить сколько памяти требуется. Можно также упомянуть вложенные прерывания (хотя перед использованием этого приема нужно крепко подумать), оценить частоту и количество вызовов, а также уровень вложенности, которых по C исходнику с помощью машины тоже вряд-ли реально. Наконец стоит вспомнить о рекурсивных функциях - какая глубина рекурсии потребуется можно сказать только при полностью известных исходных данных, т. е. в том случае когда собственно программа обрабатывает заранее известную информацию, и результат ее (программы) работы в принципе тоже известен. Например Код void some_recursive_func(int i, long int a, long int b); // некая рекурсивная функция char read_some_port(void); // функция чтения порта, возвращающая практически случайное число от 0 до 256 int main (void){ int i; long int a; i = (int)read_some_port(); // читаем в i значение порта some_recursive_func(i, a, a); // вызываем нашу рекурсивную функцию return; } void some_recursive_func(int i, long int a, long int b){ // собственно функция if (i>0){ // если i положительная, то уменьшаем ее --i; b=a++; // делаем что-то some_recursive_func (i, a, b); // вызываем функцию . Вопрос лишь в том соклько раз она вызовется (и соответсвенно сколько стека отъест)? } } Конечно приведенные примеры сильно утрированы, но они простые, а в реальности могут быть на порядки сложнее, поэтому в общем случае мое мнение таково - ни один анализатор не сможет оценить реальные потребности в памяти по C исходникам при сколько-либо сложной задаче (т. е. в том случае где это нужно).
|
|
|
|
|
Jul 21 2009, 10:05
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(alx2 @ Jul 17 2009, 16:52)  А потом пересчитывать при каждой модификации исходника... То есть просто в рукопашную, один на один с исходником? Цитата(alx2 @ Jul 17 2009, 16:52)  изначально весь стек заполняется какой-то константой, затем процесс запускается на выполнение (в симуляторе или живом устройстве), причем по возможности стараются прогнать выполнение по всем возможным веткам программы. Вот именно этот процесс (прогон по всем веткам) я и хочу автоматизировать, и уже есть соображения как. В любом случае это бутет консоль (на Visual Studio 6.0) вызываемая из makefile которой будет передоваться в командной стролке имя и путь к файлу *.lss. Попутный вопрос, как в makefile считать код возврата компилятора дабы не вызывать лишний раз консоль, да и файла тогда еще нет?  Цитата(Troll @ Jul 17 2009, 17:58)  Так для этого надо считать не указатели, а операции со стеком. Конечно, подсчет указателей нужен для определеня размера структуры в менеджере памяти. Это делается еще до компиляции, а для стека нужно учитывать след. команды: push, st,std,call... в *.lss. Можно правда избавиться от лишней компиляции (надо же получить *.lss) если анализировать файлы *.c & *.h, но огда придеться считаться с гораздо сложным синтаксисом.
Сообщение отредактировал antiwin - Jul 21 2009, 10:10
|
|
|
|
|
Jul 21 2009, 11:16
|
Частый гость
 
Группа: Участник
Сообщений: 104
Регистрация: 30-06-05
Из: С-Петербург
Пользователь №: 6 406

|
Цитата(antiwin @ Jul 21 2009, 17:05)  Вот именно этот процесс (прогон по всем веткам) я и хочу автоматизировать, и уже есть соображения как. Можно, конечно, построить дерево вызова процедур. Но возникают вопросы: - как будете учитывать рекурсивные вызовы? - вызовы прерываний, особенно если у них разные приоритеты?
--------------------
Hemos Pasado
|
|
|
|
|
Jul 21 2009, 19:52
|

Местный
  
Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091

|
Цитата(antiwin @ Jul 21 2009, 15:05)  Попутный вопрос, как в makefile считать код возврата компилятора Что значит "считать"? make и так проверяет код возврата каждой выполняемой команды на равенство нулю дабы прекратить выполнение в случае ошибки. Если в зависимости от кода возврата компилятора требуется выполнить какое-то ветвление, делайте это срадствами шелла, а не make'а.
--------------------
Всего наилучшего, Alex Mogilnikov
|
|
|
|
|
Jul 22 2009, 08:29
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(alx2 @ Jul 21 2009, 23:52)  Если в зависимости от кода возврата компилятора требуется выполнить какое-то ветвление, делайте это срадствами шелла, а не make'а. Да, именно это. Просто я в шелле пока не очень, не могли бы прислать примерчик?
|
|
|
|
|
Jul 22 2009, 14:10
|

Местный
  
Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091

|
Цитата(antiwin @ Jul 22 2009, 13:29)  Да, именно это. Просто я в шелле пока не очень, не могли бы прислать примерчик? Например вот так: Код gcc -c test.c && echo "Ура!!! Нет ошибок!" || echo "Ой, ошибка при компиляции!"
--------------------
Всего наилучшего, Alex Mogilnikov
|
|
|
|
|
Jul 23 2009, 08:31
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(smac @ Jul 17 2009, 19:33)  Сомневаюсь что Ваш анализатор справится с задачей "просто заглянув исходник". Конечно, приведенные примеры поставят в тупик анализатор, но если он истпользует уже скомпилированный файл т.е асмовый текст. При использовании исходников подобные проблемы я думаю решаемы. Конечно, и в этом случае алгоритм анализа получится довольно сложным, а в более общих случаях достаточно приблизительным, помимо этого придется анализировать все include и определенные даные . По большому счету это уже компилятор (препроцессор). Но все же... От использования исходных файлов останавливает то, что не у всех функций можно получить описание, таких как: malloc, sin random ( т.е встроенных-библиотечных)....Я эту тему чуть выше поднимал, но честно пока так и не разобрался где лежит их описание. P.S Буду очень благодарен за внесение ястности в этот вопрос.
Сообщение отредактировал antiwin - Jul 23 2009, 08:34
|
|
|
|
|
Jul 23 2009, 10:16
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(antiwin @ Jul 23 2009, 12:31)  .....что не у всех функций можно получить описание, таких как: malloc, sin random ( т.е встроенных-библиотечных)....Я эту тему чуть выше поднимал, но честно пока так и не разобрался где лежит их описание. P.S Буду очень благодарен за внесение ястности в этот вопрос. http://ftp.twaren.net/Unix/NonGNU/avr-libc/PS: Учитесь пользоваться гуглем, это очень пригодиться Вам в жизни. Анатолий.
|
|
|
|
|
Jul 23 2009, 10:55
|
Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003

|
Цитата(antiwin @ Jul 23 2009, 12:31)  Конечно, приведенные примеры поставят в тупик анализатор, но если он истпользует уже скомпилированный файл т.е асмовый текст. При использовании исходников подобные проблемы я думаю решаемы. ... Не вижу разници между асмовым текстом и сишным, ибо количество вызовов ни по одному ни по другому в тех примерах не определить, дальше обсуждать это бессмысленно. Просто мне кажется, что написание того анализатора что Вы задумываете - гораздо более сложная задача, чем написание хорошего программного эмулятора (симулятора). Если решать ее в общем случае (например для семейства процессоров), то ресурсов (имеются ввиду "человеко-часы") уйдет очень много. С другой стороны решение этой задачи в частном случае - оценка потребляемого конкретным кодом стека, тоже потребует приличного времени, при том что в частном случае она может быть решена предлагаемыми в теме способами с меньшими потерями "человеко-часов".
|
|
|
|
|
Jul 24 2009, 08:46
|
Участник

Группа: Новичок
Сообщений: 22
Регистрация: 20-05-09
Пользователь №: 49 303

|
Цитата(smac @ Jul 23 2009, 14:55)  Не вижу разници между асмовым текстом и сишным, ибо количество вызовов ни по одному ни по другому в тех примерах не определить... Разница огромна, работать с асмовым текстом все равно что глядя на кучу кирпичей гадать что это было, в случае с исходниками ситуация более ясная. Так как "глядя" на синтаксис можно очень многое узнать о текущей операции и даже если нет конкретных данных (приходят из порта), все равно можно хотя бы узнать минимальное и максимальное значение переменной, анализируя формат данных (char, int, long int...) и тип арифметической или логической операции.
|
|
|
|
|
Jul 24 2009, 09:26
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(antiwin @ Jul 24 2009, 12:46)  Разница огромна, работать с асмовым текстом все равно что глядя на кучу кирпичей гадать что это было, в случае с исходниками ситуация более ясная. Анализируя С код вы ни когда не узнаете размер frame-буфура и сколько call-used регистров будут сохранено в стеке. Точнее узеаете , но только в одном случае когда Ваш скрипт будет работать точно также как компилятор. Размер стека использованого библиотечными функциями, можно только проанализировав дизассемблированный код. Анатоллий.
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|