Дата последнего обновления файла 02.12.2005

Реализация подпрограмм на языке ASM51

Подпрограммы на языке программирования ASM-51 выносятся отдельно от основного текста программы. Обычно подпрограммы размещают после основного текста программы для того, чтобы случайно не передать управление подпрограмме не оператором вызова подпрограммы. Это может произойти из-за того, что ассемблер назначает адреса операторам в порядке их написания.

Исходный текст подпрограммы начинается с метки, которая одновременно является именем подпрограммы. Именно это имя указывается в качестве операнда в команде вызова подпрограммы LCALL. Возвращение из подпрограммы на оператор, следующий за оператором вызова подпрограммы осуществляется оператором RET. Все операторы, которые должны быть выполнены в подпрограммы располагаются между меткой, обозначающей имя подпрограммы и оператором возврата из подпрограммы.

Реализация подпрограмм-процедур на языке ASM51

Подпрограмма процедура вызывается командами процессора LCALL и ACALL. В языке программирования ASM51 допустимо использования директивы CALL эта директива подбирает наиболее подходящую к данному случаю по размеру команду.

Пример подпрограммы управления последовательным портом:

Рисунок 1. Пример подпрограммы - процедуры.

Передача переменных-параметров в подпрограмму.

В приведённом выше примере байт передаётся в подпрограмму через глобальную переменную G_Per. Однако программа будет эффективнее при использовании подпрограммы с параметрами. Мы знаем, что параметр подпрограммы - это локальная переменная. В этом случае могут значительно снизиться требования к памяти данных. Для размещения локальных переменных лучше всего использовать внутренние регистры процессора. На языке ASM51 для передачи параметра размерностью один байт обычно используется аккумулятор как показано в примере программы, приведённом на рисунке 2.


Рисунок 2. Пример подпрограммы-процедуры с передачей байта через аккумулятор

Вызов такой подпрограммы на языке программирования С выглядел бы следующим образом:

Если в подпрограмму нужно передать двухбайтовое значение, то в качестве параметра подпрограммы используется пара регистров (обычно регистры R6-старший байт и R7-младший байт). Пример программы, передающей в подпрограмму двухбайтовое число, написанной на языке программирования ASM-51 приведён на рисунке 3.

Рисунок 3. Пример подпрограммы - процедуры с передачей двухбайтного числа через регистры R7 и R6.

Если в подпрограмму нужно передать четырёхбайтовое значение (это требуется для переменной, соответствующей типу long или float), то используются регистры R4...R7 (регистр R4 - старший байт):

Регистры R0 и R1 обычно используются в качестве указателей обрабатываемых переменных таких как строки или массивы. Если требуется, чтобы подпрограмма обработала значительный объём данных, как например:

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

Рисунок 4. Пример подпрограммы - процедуры с передачей адреса строки через регистр DPTR.

При обращении к массивам или структурам, расположенным во внутренней памяти данных в качестве указателя адреса используется регистр R0 или R1. Пример передачи в подпрограмму массива в качестве параметра, написанный на языке программирования ASM-51 приведён на рисунке 5:

Рисунок 5. Пример подпрограммы - процедуры с передачей адреса массива через регистр R0.

Реализация подпрограмм-функций на языке ASM51.

Часто требуется передавать результат вычислений из подпрограммы в основную программу. Для этого можно воспользоваться подпрограммой - функцией. Подпрограмма - функция возвращает вычисленное значение. Пример использования подпрограммы - функции на языке программирования высокого уровня:

Как видно из приведённого примера, использование подпрограмм-функций значительно увеличивает наглядность программ и приближает запись на языке программирования к записи математического выражения. На языке программирования ASM51 этот же вызов подпрограммы-функции выглядит следующим образом:

В этом примере подпрограмма вычисления синуса перед выполнением оператора возврата в основную программу должна поместить результат вычисления синуса в аккумулятор.

Подпрограмма - функция может возвращать и многобайтовые переменные, используя регистр - указатель R0 или R1. Однако для копирования этих переменных потребуется ещё одна подпрограмма копирования.

Реализация подпрограмм обработки прерываний на языке ASM51

Как известно, подпрограммы обработки прерываний вызываются аппаратурой, поэтому эти подпрограммы не могут иметь параметров. Кроме того эти подпрограммы не могут быть подпрограммами-функциями. При возвращении из подпрограммы обработки прерывания должны быть разрешены дальнейшие прерывания, поэтому возврат из подпрограммы обработки прерывания может быть осуществлён только командой RETI.

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

Рисунок 6. Пример подпрограммы обработки прерывания.

В приведённом примере директива CSEG AT 0BH использована для того, чтобы разместить подпрограмму обработки прерывания на вектор прерывания от таймера 0.

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


Рисунок 7. Пример подпрограммы обработки прерывания

Если подпрограмма обработки прерывания использует несколько регистров, то на сохранение регистров в стеке и на восстановление их из стека тратится достаточно много времени. Микроконтроллеры семейства MCS-51 предлагают возможность использовать для подпрограмм прерываний отдельный банк регистров. В языке программирования ASM-51 то, что программа использует не нулевой банк регистров отображается при помощи директивы USING как это показано в примере на рисунке 8.

Рисунок 8. Пример подпрограммы обработки прерывания с использованием второго банка регистров.

Литература:

  1. Микушин А.В. Сединин В.И. Однокристальный микроконтроллер семейства MCS-51 фирмы INTEL 8xC51GB Новосибирск: СибГУТИ, 2001
  2. Микушин А.В. Сединин В.И. Программирование микропроцессорных систем на языке ASM-51 Новосибирск: СибГУТИ, 2003
  3. Микушин А.В. Занимательно о микроконтроллерах. СПб, БХВ-Петербург, 2006.
  4. Микушин А.В., Сажнев А.М., Сединин В.И. Цифровые устройства и микропроцессоры. СПб, БХВ-Петербург, 2010.

Вместе со статьей "Реализация подпрограмм на языке ASM51" читают:

Языки программирования для микроконтроллеров
http://digteh.ru/Progr/progr.php

Язык программирования ASM-51
http://digteh.ru/MCS51/ASM51/asm51.php

Структурное программирование на языке ASM-51
http://digteh.ru/MCS51/ASM51/strprogr.php

Многомодульные программы на языке программирования ассемблер
http://digteh.ru/MCS51/ASM51/manymod.php


Автор Микушин А. В. All rights reserved. 2001 ... 2015

Предыдущие версии сайта:
http://neic.nsk.su/~mavr
http://digital.sibsutis.ru/

пЕИРХМЦ@Mail.ru


Rambler's Top100