Что такое стек? Как он работает? — КиберПедия


Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...

Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого...

Что такое стек? Как он работает?



 

Стек – это память для хранения адресов возврата. Обычно для его объяснения, приводят пример с книжной полкой. По сути, так и есть, и даже проще. Стек может быть реализован программно или аппаратно, что быстрее. У данного МК, он реализован аппаратно, имеет разрядность 13 бит, и 8 уровней вложенности. Это значит, что функция может вызвать сама себя 8 раз. На 9 – новый адрес – запишется на место 1, и после этого ваша программа зациклится, потому что стек будет переполнен, а адрес возврата утерян.

Чтобы разобраться, как он работает, и что делают команды call и return, наберите эту небольшую программу.

 

;---------------------------------- ;

#include<p17С756А.inc>

 

;---------------------------------- ;

org 0x00

 

goto main

 

org 0x05

 

;---------------------------------- ;

; Функции программы

;---------------------------------- ;

Call_1:

nop

nop

 

return

;--------------------------------- ;

Call_2:

 

nop

nop

 

return

;---------------------------------- ;

main:

call Call_1 ;

call Call_2 ;

 

goto main

 

END

 

В пункте меню View, активируйте подпункт Hardware Stack (рис.4.2).

 

Рис.4.2 - Стек

 

Запустите программу в отладчике, используя ручной режим. Нажимая клавишу <F7>, последовательно доберитесь до строки:

 

call Call_1 ; вызов функции Call_1

 

Ниже представлена упрощённая версия, файла листинга программы, созданного компилятором. Просто взгляните, а потом продолжите чтение.

 

Address:

0000 org 0x00

 

0000 goto main

 

0005 org 0x05

;--------------------

0005 Call_1:

0005 nop

0006 nop

0007 return

;--------------------

0008 Call_2:

 

0008 nop

0009 nop

 

000A return

;--------------------

000B main:

000B call Call_1 ;

000C call Call_2 ;

 

000D goto main

 

END

 

Имя функций Call_1 указывает на адрес 0х05, по которому размещена первая команда в памяти программ – nop. За ней ещё одна в ячейке памяти под номером - 0х06, и оканчивается функция командой возврата return, расположившейся в ячейке - 0х07.

 

0005 Call_1:

0005 nop

0006 nop

0007 return

 

Вспомните, когда мы рассматривали метки, упоминалось, что они являются средством организации программы на уровне пользователя. Как видите, так и есть, потому, что по адресу 0х05 располагается команда nop.

Теперь взгляните на адрес 0х0B (D‘11’), с которого начинается метка ‘main’, и следует команда вызова функции Call_1.

 

000B main:

000B call Call_1 ;

000C call Call_2 ;

 

000D goto main

 

END

 

При выполнении команды call – произойдёт следующее: текущий адрес 0x0B, на который указывает счётчик команд - PC, будет увеличен на 1 – PC + 1, то есть: 0x0B + 0x01 = 0x0C, после чего, тем самым начнёт указывать на следующую команду в памяти программ, и будет загружен в вершину стека (рис.4.3.). Произойдёт неявное выполнение команды goto на адрес 0х05, с которым ассоциирована метка подпрограммы Call_1.



 

Рис.4.3 - Стек после вызова функции

 

Когда все команды в теле функции Call_1 будут выполнены, и дело дойдёт до команды возврата return, произойдёт обращение к стеку, и выполниться переход по адресу, в нашем случае - это 0х0C, на который обращён указатель, и который был загружен в вершину стека командой вызова функции call. Это тем самым вернёт управление основной программе, и начнёт выполнение следующей команды, расположенной по адресу 0х0С. Если подобное описание автора показалось вам сложным, обратитесь к описанию системы команд, где данная информация представлена в более сжатой форме.

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

 

Соглашения об именовании

 

Выполнив уже две лабораторные работы, пришло время ознакомиться, с некоторыми правилами об именовании переменных и остальных членов программ. Имя – это уникальный идентификатор объекта, характеризующий его основные качества. Как было сказано в лабораторной работе № 2 – ячейка памяти, которая с чем-то ассоциирована, считается переменной. Чем больше информации способно нести имя, тем понятнее назначение члена в программе. Для удобства, автор использует один и тот же стиль во всех примерах, когда наделяет именами функции, метки и переменные. Если вы уже имели опыт программирования, и выработали для себя определённый стиль, тогда, конечно же, вам следует придерживаться его. В целях повышения читабельности кода, ознакомьтесь с соглашениями об именовании членов программ.

Переменные

 

Имена переменных обычно начинаются со строчной буквы. Это правило может быть нарушено, когда в программе используются копии реальных имён логического выражения, для повышения читабельности.

 

value EQU 0x20 ;

array EQU 0x21 ;

 

X1 EQU 0x22 ;

X2 EQU 0x23 ;

X3 EQU 0x24 ;

 

Переменные, которые состоят из нескольких слов – оба пишутся с маленькой буквы, и разделены знаком нижнего пробельного символа ‘_’. Если имена слишком длинные, сокращение происходит по согласным. В противном случае, слова остаются в том же виде. Также это правило нарушается для логических выражений.



 

arr_size EQU 0x21 ;

 

n_X1 EQU 0x22 ; инвертированный Х1

 

Функции и Макросы

 

Одиночные имена функций состоят из одного слова с заглавной буквы.

 

Calc: ;

 

return

 

Составные имена – оба слова начинаются с заглавных букв, разделенных знаком нижнего пробельного символа ‘_’. В случае длинного названия, сокращение идёт по согласным.

 

Calc_Array: ;

.

.

return

 

Init_Vars: ;

.

.

return

 

Strt_Tmr1: ;

 

 

ENDM

 

Метки

 

Главная метка программы ‘main’ всегда начинается со строчной.

 

main:

.

.

END

 

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

 

main:

 

A2:

goto A2 ;

.

.

.

AT2:

goto AT2

 

END

 

Команды

 

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

 

movwl D‘10’ ;

bsf value,2 ;

 

Директивы

 

Директивы #include, #define, а также имена подключаемых файлов состоят из строчных букв. Остальные состоят только из заглавных.

 

#include<source_file> ;

#define true 0x01 ;

.

.

#include”source­_file”

#define false 0x00 ;

.

.

BANKSEL label ;

.

.

label EQU address ;

 






Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого...

Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...

Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...

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





© cyberpedia.su 2017-2020 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.014 с.