В настоящее время часто пользуются интегрированными средами программирования, например, фирм Franclin или keil, в состав которых входит язык программирования ASM-51. В этих программах создание строки вызова редактора связей производится автоматически при настройке программного проекта, а вызов редактора связей при помощи этой строки производится в ходе построения программного проекта. Настройка программного проекта происходит при подключении к нему новых программных модулей и при изменении его свойств, таких как разрешение или запрет создания карты памяти программы, выбор папки для хранения выходных файлов, разрешение или запрет помещения в выходной файл отладочной информации, разрешение или запрет создания загрузочного НЕХ-файла.
При трансляции программы по частям возникает вопрос, как с этими частями работать. Иначе говоря, дает о себе знать проблема сегментов.
Справедливости ради необходимо отметить, что даже когда мы не задумываемся о сегментах, в программе присутствуют два сегмента: сегмент кода и сегмент данных. Если внимательно присмотреться к программе, то можно обнаружить, что кроме кодов команд в памяти программ хранятся константы, т. е. в памяти программ микроконтроллера располагаются, по крайней мере, два сегмента: код и данные. Чередование кода и данных может привести к нежелательным последствиям. Вследствие каких-либо причин данные могут быть случайно выполнены в качестве машинных команд или наоборот коды машинных команд могут быть восприняты и обработаны как данные.
Перечисленные выше причины приводят к тому, что желательно явным образом выделить, по крайней мере, четыре сегмента:
1) кода;
2) переменных;
3) стека;
4) констант.
И лучше, если эти сегменты будут перемещаемыми. Тогда редактор связей сможет автоматически скомпоновать программу наилучшим способом.
Пример размещения сегментов в адресном пространстве памяти программ и внутренней памяти данных приведен на рис. 8.4. На этом рисунке видно, что при использовании нескольких сегментов переменных во внутренней памяти данных редактор связей может разместить меньший из них на месте неиспользованных банков регистров. Под сегмент стека обычно отводится вся область внутренней памяти, не занятая переменными. Это позволяет создавать программы с максимальным уровнем вложенности подпрограмм. Сегмент переменных, расположенный на рис. 8.4 во внешней памяти данных, при использовании современных микросхем, таких как AduC842, может находиться и в ОЗУ, расположенном на кристалле микроконтроллера.
Наиболее простой способ определения сегментов — это использование абсолютных сегментов памяти. При этом способе распределение памяти ведется вручную точно так же, как это делалось при использовании директивы EQU. В этом случае начальный адрес сегмента жестко задается программистом, и он же следит за тем, чтобы сегменты не перекрывались друг другом в памяти микроконтроллера. Использование абсолютных сегментов позволяет более гибко работать с памятью данных, т. к. теперь байтовые переменные в памяти данных могут быть назначены при помощи директивы резервирования памяти DS, а битовые переменные при помощи директивы резервирования битов DBIT.
Рис. 8.4.
Для определения абсолютных сегментов памяти используются следующие директивы:
— BSEG — абсолютный сегмент в области битовой адресации;
— CSEG — абсолютный сегмент в области памяти программ;
— DSEG — абсолютный сегмент в области внутренней памяти данных;
— ISEG — абсолютный сегмент в области внутренней памяти данных с косвенной адресацией;
— XSEG — абсолютный сегмент в области внешней памяти данных.
Пример использования директивы BSEG для объявления битовых переменных приведен в листинге 8.24.