Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Вопрос к Гуру! Что интереснее функция или подпрограмма?


Вопрос к Гуру! Что интереснее функция или подпрограмма?

Сообщений 1 страница 9 из 9

1

Вот в чём вопрос! :)

Есть функция

Функция

'-------------------------------------------------------------------------------
' Circle        show 1-не заполненный круг 2-заполненный круг 3-заполненный круг с бордюром
' ширина бордюра в пикселях (ширна внутрь от внешнего радиуа)
'
'-------------------------------------------------------------------------------
Sub Ili9325_circle(byval X As Word , Byval Y As Word , Byval Radius As Byte , Byval Show As Byte , Byval Color As Word , Byval Border_color As Word , Byval Border_width As Byte)
Local Count_y As Integer , Count_x As Integer
Local Y1 As Integer , X1 As Integer , Xy As Integer , Xy_radius As Integer
Local Y11 As Integer , X11 As Integer
Local Temp_x As Word , Temp_y As Word , Temp_border As Byte , Temp_radius As Byte
Reset_window


          If Show = 2 Or Show = 3 Then

Xy_radius = Radius * Radius
Y1 = -radius
X1 = -radius

For Count_y = Y1 To Radius
   Y11 = Count_y * Count_y
   Temp_y = Y + Count_y

   For Count_x = X1 To Radius
      X11 = Count_x * Count_x
      Xy = X11 + Y11
      If Xy <= Xy_radius Then
         Temp_x = X + Count_x

   Call Ili9325_set_pixel(temp_x , Temp_y , Color)
      End If
   Next Count_x
Next Count_y
          End If

          If Show = 1 Or Show = 3 Then
Temp_radius = Radius
For Temp_border = 1 To Border_width
Xy_radius = Temp_radius * Temp_radius
For Count_y = 0 To Temp_radius
   Y1 = Count_y * Count_y
   For Count_x = Temp_radius To 0 Step -1
       X1 = Count_x * Count_x
       Xy = X1 + Y1
       If Xy <= Xy_radius Then
          Temp_y = Y - Count_x : Temp_x = X + Count_y : Gosub Set_point
          Temp_y = Y + Count_x : Gosub Set_point
          Temp_y = Y - Count_x : Temp_x = X - Count_y : Gosub Set_point
          Temp_y = Y + Count_x : Gosub Set_point
          Temp_y = Y - Count_y : Temp_x = X + Count_x : Gosub Set_point
          Temp_y = Y + Count_y : Gosub Set_point
          Temp_y = Y - Count_y : Temp_x = X - Count_x : Gosub Set_point
          Temp_y = Y + Count_y : Gosub Set_point
          Exit For
       End If
   Next Count_x
Next Count_y
Goto End_sub_circle

Set_point:
   Call Ili9325_set_pixel(temp_x , Temp_y , Border_color)
Return

End_sub_circle:
Decr Temp_radius
Next Temp_border
          End If
End Sub
'-------------------------------------------------------------------------------

Есть вызов этой функции
Call Ili9325_circle(170 , 50 , 40 , 2 , Red , Red , 2)
Call Ili9325_circle(110 , 50 , 40 , 3 , Yellow , Black , 3)

Дак вот каждый вызов этой функции занимает около 150 байт (вычислено практическим путем)

А если оформить эту функцию в ввиде подпрограммы, то присваиваем  вводным переменным нужные значения
и командой gosub уходим на подпрограмму. Экономия памяти существенная.
Но
Как большое количество команд gosub сказывается на необходимом объеме стека?

Что сможете посоветовать?

-1

2

зависит от компилятора
на стек может вообще не сказываться, а вот на объём выполняемого кода - да
обычно gosub - это подпрограмма, которая либо вставляется куском кода в это место (повторяется) или выполняется тот же call (это обычно минус 2 байта в стеке)

-1

3

Ну Мы как бы баском в качестве компилятора рассматриваем! :)

Если я правильно понимаю, то каждая команда gosub в теле программы это + 2 байта к стеку?
При использовании call стек не нужен, но требуется больше пзу?
Либо кончится память, либо кончится оперативка!
А третьего не дано???

-1

4

Геныч написал(а):

Если я правильно понимаю, то каждая команда gosub в теле программы это + 2 байта к стеку?

В коде много вложенных вызовов подпрограмм или есть рекурсия?

Геныч написал(а):

При использовании call стек не нужен, но требуется больше пзу?

Нужен, еще как нужен.
Стек как и в случае подпрограммы, используется для сохранения адреса возврата, а так же для хранения аргументов, т. е. еще больше стековой памяти используется.
Пишите под МК с малым объемом памяти или вообще без нее? Иначе просто задайте больше памяти под стек.

0

5

Цель вывод динамики на tft дисплей 320 на 240 из примитивов
все примитивы в данный момент написаны функциями, память как всегда в дифиците.
соответственно вызовов функций достаточно много, упёрся в память
Можно вызывать функцию из подпрограммы, это экономит память, но требует дополнительных переменных, получается делаю дубликаты переменных которые используются в функции.
Всё таки склоняюсь к подпрограммам, но оперативка тоже не резиновая. :(

-1

6

Функция:

"+"
красивее смотрится
проще пользоваться
меньше глобальных переменных

"-"
вход и выход занимает слишком много времени
при некоторых условиях, непредсказуемый результат

Корректная работа функции зависит от правильного использования регистров, т.е., переход в подпрограмму с аргументами. К сожалению Bascom очень часто генерирует непонятно что.
Переменные налазят одна на другую, в итоге имеем непредсказуемый результат

Подпрограмма:

"+"
скорость работы
нет проблем в работе, результат абсолютно предсказуем

"-"
неудобно пользоваться, аргументы нужно передавать вручную
растёт количество глобальных переменных

Отредактировано sasha_1973 (2014-11-24 12:43:29)

0

7

Геныч написал(а):

все примитивы в данный момент написаны функциями, память как всегда в дифиците.
соответственно вызовов функций достаточно много, упёрся в память


Я давно говорил и продолжаю говорить, что надо отказываться от функций - это неконтролируемое сборище утечек памяти. Я лично не использую их вообще и около 50% проблем не имею.

0

8

А подскажите такую вещь!
Баском при компиляции резервирует под каждый gosub место в стеке?
Или если программа линейная, то при gosub пишется 2байта точки возврата в стек
При возврате из подпрограммы эти 2 байта освобождаются.

При наличии рекурсии соответственно суммируются все переходы от начальной точки и до возврата на неё?
При возврате на начальную точку данные из стека стираются?

Я правильно это понимаю?

0

9

Баском ничего не резервирует, это обычная работа/архитектура МК. Вы бы хоть почитали азы, коль начинаете лезть в эту область, а то у вас понятия...

При рекурсии у вас идет переполнение стека. За этим вы сами должны смотреть.
В своё время, я на подобную тему общался с автором Баском, он мне на эти все хитрые операции с стеком ответил просто - нет, т.е. он не будет добавлять функционал/инструмент запоминания адреса стека для корректного выхода при многократном, самовызове.
Вообще такой подход - это неправильное программирование! Каждый gosub должен иметь return.
В любом случае, если такое ну очень нужно, то придется уходить на ассемблер.

+1


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Вопрос к Гуру! Что интереснее функция или подпрограмма?