Использование сегментов в языке программирования ассемблер 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Использование сегментов в языке программирования ассемблер



При трансляции программы по частям возникает вопрос, как с этими частями работать. Иначе говоря, дает о себе знать проблема сегментов. Справедливости ради необходимо отметить, что даже когда мы не задумываемся о сегментах, в программе присутствует два сегмента: сегмент кода и сегмент данных. Если внимательно присмотреться к программе, то можно обнаружить, что кроме кодов команд в памяти программ хранятся константы, то есть в памяти программ микроконтроллера располагаются, по крайней мере, два сегмента: код и данные. Чередование кода и данных может привести к нежелательным последствиям. Вследствие каких-либо причин данные могут быть случайно выполнены в качестве машинных команд или наоборот коды машинных команд могут быть восприняты и обработаны как данные.

Рис. 23.4. Разбиение памяти программ и памяти данных на сегменты

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

ú Кода;

ú Переменных;

ú Стека;

ú Констант.

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

Пример размещения сегментов в адресном пространстве памяти программ и внутренней памяти данных приведен на рис. 23.4. На этом рисунке видно, что при использовании нескольких сегментов переменных во внутренней памяти данных редактор связей может разместить меньший из них на месте неиспользованных банков регистров. Под сегмент стека обычно отводится вся область внутренней памяти, не занятая переменными. Это позволяет создавать программы с максимальным уровнем вложенности подпрограмм. Сегмент переменных, расположенный на рис. 23.4 во внешней памяти данных, при использовании современных микросхем, таких как AduC842, может находиться в ОЗУ, расположенном на кристалле микроконтроллера.

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

Для определения абсолютных сегментовпамяти используются следующие директивы:

q BSEG - абсолютный сегмент в области битовой адресации;

q CSEG - абсолютный сегмент в области памяти программ;

q DSEG - абсолютный сегмент в области внутренней памяти данных;

q ISEG - абсолютный сегмент в области внутренней памяти данных с косвенной адресацией;

q XSEG - абсолютный сегмент в области внешней памяти данных.

Директива bseg позволяет определить абсолютный сегмент во внутренней памяти данных с битовой адресацией по определенному адресу. Эта директива не назначает имени сегменту, то есть объединение сегментов из различных программных модулей невозможно. Для определения конкретного начального адреса сегмента применяется атрибут AT. Если атрибут AT не используется, то начальный адрес сегмента предполагается равным нулю. Использование битовых переменных позволяет значительно экономить внутреннюю память программ микроконтроллера. Пример использования директивы BSEG для объявления битовых переменных приведен в листинге 23.24.

Листинг 23.24. Пример использования директивы BSEG перед определениями битовых переменных

BSEG AT 8;Сегмент начинается с восьмого бита

RejInd DBIT 1;Флаг режима индикации

RejPriem DBIT 1;Флаг режима приема

Flag DBIT 1;Флаг общего назначения

Директива cseg позволяет определить абсолютный сегмент в памяти программ по определенному адресу. Директива не назначает имени сегменту, то есть объединение сегментов из различных программных модулей невозможно. Для определения конкретного начального адреса сегмента применяется атрибут AT. Если атрибут AT не используется, то начальный адрес сегмента предполагается равным нулю. Пример использования директивы CSEG для размещения подпрограммы обслуживания прерывания от таймера 0 приведен в листинге 23.25.

Листинг 23.25. Пример использования директивы cseg для размещения подпрограммы обслуживания прерывания

;Перезагрузка таймера-----------------------------------------

CSEG AT 0bh;Вектор прерывания от таймера 0

IntT0:

mov TL0, #LOW(-(F_ZQ/12)*10-2);Настроить таймер

mov TH0, #HIGH(-(F_ZQ/12)*10-2);на период 10мс

reti

Директива dseg позволяет определить абсолютный сегмент во внутренней памяти данных по определенному адресу. Предполагается, что к этому сегменту будут обращаться команды с прямой адресацией. Эта директива не назначает имени сегменту, то есть объединение сегментов из различных программных модулей невозможно. Для определения конкретного начального адреса сегмента применяется атрибут AT. Если атрибут AT не используется, то начальный адрес сегмента предполагается равным нулю. Пример использования директивы DSEG для объявления байтовых переменных приведен в листинге 23.26.

Листинг 23.26. Пример использования директивы DSEG перед определением байтовых переменных

DSEG AT 20;Разместить сегмент в битовом пространстве микроконтроллера

;(для возможности одновременно битовой и байтовой адресации)

RejInd DS 1;Переменная, отображающая состояние программ обслуживания

;аппаратуры

Rejim DS 1;Переменная, отображающая режимы работы

Massiv DS 10;Десятибайтовый массив

Последний пример связан с примером, приведенным в листинге 23.24. То есть команды, изменяющие битовые переменные RejInd, RejPriem или Flag, одновременно будут изменять содержимое переменной Rejim, и наоборот команды, работающие с переменной Rejim, одновременно изменяют содержимое флагов RejInd, RejPriem или Flag. Такое объявление переменных позволяет написать наиболее эффективную программу управления контроллером и подключенными к нему устройствами.

Директива iseg позволяет определить абсолютный сегмент во внутренней памяти данных с косвенной адресацией по определенному адресу. Напомню, что адресное пространство внутренней памяти с косвенной адресацией в два раза больше адресного пространства памяти с прямой адресацией. Именно в этой области памяти размещается стек. ДирективаISEG не назначает имени сегменту, то есть объединение сегментов из различных программных модулей невозможно. Для определения конкретного начального адреса сегмента применяется атрибут AT. Если атрибут AT не используется, то начальный адрес сегмента предполагается равным нулю. Пример использования директивы ISEG для объявления байтовых переменных приведен в листинге 23.27.

Листинг 23.27. Пример использования директивы iseg для объявления байтовых переменных

ISEG AT 80;Разместить сегмент в диапазоне адресов, совмещенных с SFR

 

Bufer DS 10;Десятибайтовый массив

Stack DS 245;Стек

Директива xseg позволяет определить абсолютный сегмент во внешней памяти данных по определенному адресу. Эта директива не назначает имени сегменту, то есть объединение сегментов из различных программных модулей невозможно. Для определения конкретного начального адреса сегмента применяется атрибут AT. Если атрибут AT не используется, то начальный адрес сегмента предполагается равным нулю. До недавнего времени использование внешней памяти не имело смысла, так как это значительно увеличивало габариты и цену устройства. Однако в последнее время ряд фирм стал размещать на кристалле значительные объемы ОЗУ, доступ к которому осуществляется как к внешней памяти. Так как эта директива применяется так же, как DSEG, то отдельный пример приводиться не будет.

Использование абсолютных сегментов позволяет облегчить работу программиста по распределению памяти микроконтроллера для различных переменных. Однако в большинстве случаев абсолютный адрес переменной нас совершенно не интересует. Исключение составляют только регистры специальных функций. Так зачем же вручную задавать начальный адрес сегментов?

Одна из ситуаций, когда нас не интересует начальный адрес сегмента — это программные модули. Как уже говорилось ранее, в программные модули обычно выносятся подпрограммы. Естественно, что конкретные адреса, по которым будут находиться эти подпрограммы в адресном пространстве микроконтроллера, нас тоже мало интересует.

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

Директива segment позволяет определить имя сегмента и область памяти, где будет размещаться данный сегмент памяти. Для каждой области памяти определено ключевое слово:

q data – размещает сегмент во внутренней памяти данных с прямой адресацией;

q idata – размещает сегмент во внутренней памяти данных с косвенной адресацией;

q bit – размещает сегмент во внутренней памяти данных с битовой адресацией;

q xdata – размещает сегмент во внешней памяти данных;

q code – размещает сегмент в памяти программ.

 

После определения имени сегмента можно использовать этот сегмент при помощи директивы rseg.

Директива rseg позволяет поместить в конкретный перемещаемый сегмент переменные или фрагмент кода программы. Обращение к одному и тому же сегменту может осуществляться в разных местах исходного текста программы (даже в разных файлах) При этом все участки сегмента будут находиться в соседних участках области памяти микроконтроллера, выделенного для этого сегмента.

Использование сегмента зависит от области памяти, для которой он предназначен. Если это память данных, то в сегменте объявляются байтовые или битовые переменные. Если это память программ, то в сегменте размещаются константы или участки кода программы. Пример использования директив segment и rseg для определения байтовых переменных во внутренней памяти данных с косвенной адресацией приведен в листинге 23.28.

Листинг 23.28. Пример использования директив segment и rseg для определения байтовых переменных

_data segment idata

public VershSteka

 

;Определение переменных----------------------------

rseg _data

buferKlav: ds 8

VershSteka:

End

В этом примере объявлен массив buferKlav, состоящий из восьми байтовых переменных. Кроме того, в данном примере объявлена переменная VershSteka, соответствующая последней ячейке памяти, используемой для хранения переменных. Переменная VershSteka может быть использована для начальной инициализации указателя стека для того, чтобы отвести под стек максимально доступное количество ячеек внутренней памяти. Это необходимо для того, чтобы избежать переполнения стека при вложенных вызовах подпрограмм.

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

Еще один пример использования директив segment и rseg приведен в листинге 23.29. В этом примере директива segment используется для определения сегмента битовых переменных.

Листинг 23.29. Пример использования директив segment и rseg для определения битовых переменных

_bits segment bit

public knIzm,strVv

 

;Определение битовых переменных -------------------------------------

rseg _bits

knIzm: dbit 1

strVv: dbit 1

end

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

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

В приведенном примере использовано имя перемещаемого сегмента _code. Оно было объявлено в самой первой строке исходного текста программы. Конкретное имя перемещаемого сегмента может быть любым, но как уже говорилось ранее оно должно отображать ту задачу, которую решает данный конкретный модуль.

Листинг 23.30. Пример использования директив segment и rseg в программном модуле

_code segment code

 

;Старт программы----------------------------------------------

CSEG AT 0;Вектор рестарта процессора

reset:

jmp main

 

;Начало основной программы микроконтроллера -------------------------

rseg _code

main:

MOVX @DPTR,A

mov SP,#VershSteka;Настроить указатель стека на вершину стека

call init;Настроить микроконтроллер

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

Итак, подведем итоги

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

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


 

АSM‑51, 1

абсолютный сегмент, 32

арифметические операции, 8

восьмеричное число, 8

Вспомогательные слова, 7

Встроенные имена, 7

двоичное число, 8

десятичное число, 8

Директива BSEG, 32

Директива CSEG, 32

Директива db, 12

Директива DSEG, 33

Директива dw, 13

Директива equ, 10

директива EXTRN, 29

Директива ISEG, 33

Директива org, 14

директива PUBLIC, 29

Директива rseg, 35

Директива segment, 34

Директива set, 11

Директива using, 15

Директива XSEG, 34

Директивы, 7

Загрузочный модуль, 2

запись комментариев, 4

идентификатор, 10

Идентификатор, 6

Идентификатор внешнего имени, 29

Инструкции, 6

исполняемый модуль, 1

источник данных, 3

Ключевое слово, 6

Команда debug/nodebug, 16

Команда include., 16

Команда pagelength, 16

Команда pagewidth, 16

Команды list/nolist, 16

комбинации знаков, 5

линейная цепочка операторов, 25

литеральная константа, 9

литеральная строка, 10

логические операции, 9

мнемоническое обозначение команды, 3

Многомодульные программы, 29

одноместная операция, 9

операнд, 3

Оператор, 2

Оператор языка программирования ASM-51, 3

Операции в ассемблере, 7

Определяемые имена, 7

параметр подпрограммы, 18

перемещаемый сегмент, 36

Подпрограмма обработки прерываний, 22

Подпрограмма-процедура, 17

Подпрограмма-функция, 21

Подпрограммы на языке программирования ASM-51, 17

Поле комментария, 4

Поле метки, 3

Поле операции, 3

приемник результата операции, 3

программного проекта, 30

программный проект, 30

пустой оператор, 3

сегмент, 31

символ интервала, 4

Символ интервала, 4

структурное программирование, 24

тип памяти, 29

УПРАВЛЯЮЩИЕ КОМАНДЫ, 15

условное выполнение оператора, 26

Файл-заголовок, 30

цикл с проверкой условия до тела цикла, 28

цикл с проверкой условия после тела цикла, 27

шестнадцатеричное число, 8

шестнадцатеричные цифры, 4

 



Поделиться:


Последнее изменение этой страницы: 2017-02-07; просмотров: 456; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.118.145.114 (0.09 с.)