02_Написание_ассемблерных_программ_Информ_материал_СПО_ч2 (1268618), страница 6
Текст из файла (страница 6)
Если вы сопрягаете вашиассемблерные подпрограммы с Си-программами, то эти подпрограммы должны находиться в отдельныхперемещаемых сегментах, а имена сегментов должны соответствовать принятым в Cx51 стандартам.Сегмент стекаПриложение для 8051 должно установить указатель стека на область памяти, которая небудет использована другими переменными. Для классических производных 8051 долженбыть определен сегмент стека, и для него должно быть зарезервировано пространство, какпредставлено ниже.STACKSEGMENTRSEGDSIDATASTACK10HЗатем вы должны инициализировать указатель стека в начале вашей програмы (абсолютный сегмент класса CODE следует начинать с нулевого адреса).CSEGAT 0JMP STARTUPSTARTUP:MOV SP, #STACK-1Абсолютные сегментыАбсолютные сегменты размещаются в фиксированных ячейках памяти.
Абсолютные сегменты создаются директивами: CSEG, DSEG, XSEG, ISEG, BSEG. Эти директивы разрешают вам размещать код и данные или резервировать пространство памяти в фиксированных ячейках памяти. Вы используете абсолютные сегменты, когда вам нужен доступ кфиксированной области памяти или когда вы хотите поместить программный код иликонстанты-данные по фиксированному адресу памяти.Сегмент по умолчаниюПо умолчанию ассемблер полагает, что выбран сегмент CODE, и устанавливает СА в0000H, когда он начинает обрабатывать исходный ассемблерный модуль. Это позволяетвам создавать программы без указания директив сегментирования.Директива SEGMENTДиректива SEGMENT используется для объявления перемещаемого сегмента.
При этоммогут быть указаны типы перемещения и выравнивания сегмента. Формат директивы:SegNameSEGMENT class reloctype alloctypeгдеSegName — имя, назначенное сегменту. Это имя указывается в рассматриваемой нижедирективе RSEG. Имя сегмента может использоваться в выражениях для представлениябазового или стартового адреса объединенного сегмента, вычисленного редактором связей (линкер).class — класс памяти. Имя сегмента в каждом модуле должно быть уникальным. Однако редактор связей (линкер) объединяет сегменты одинакового типа.
Это правило такжераспространяется на сегменты, объявленные в других модулях. Класс используется линкером для доступа ко всем сегментам, принадлежащим данному классу. Базовые классыперечислены ниже:25Базовый классОписаниеBITБитовая область внутреннего ОЗУ (адреса 20H...2FH)CODEОбласть программной памяти (ПЗУ)DATAПрямоадресуемая область внутреннего ОЗУ (адреса 0…7FH и РСФ: 80H...FFH)IDATAКосвенно адресуемая область внутреннего ОЗУ (адреса 0…FFH)XDATAОбласть внешнего ОЗУreloctype — тип перемещения для сегмента. Он определяет дополнительные операцииперемещения, которые могут быть исполнены линкером.
Следующая таблица содержитсписок допустимых типов перемещения:Тип перемещенияBITADDRESSABLEINBLOCKINPAGEOVERLAYABLEОписаниеСпецифицирует сегмент, который будет размещен в области внутреннего ОЗУ с побитовой адресацией (20H...2FH в области DATA). Т.е. в области BIT заводится байтовая переменная, и тогда можно обращаться к каждому биту переменной. Этот типперемещения допустим только для сегментов класса DATA, размер которых не превышает 16 байтов.Устанавливает сегмент, который должен включаться в блок, размером 2048 байтов.Этот тип перемещения допустим только для сегментов с классом CODE.Специфицирует сегмент, который должен содержаться в странице памяти, размером256 байтов.Указывает, что сегмент может совместно использовать память с другими сегментами.Сегменты, объявленные с этим типом перемещения, могут перекрываться другимисегментами, также объявленными с типом перемещения OVERLAYABLE. При использовании этого типа перемещения имя сегмента должно объявляться в соответствии с правилами назначения имен в C251, CX51, C51 или PL/M-51.alloctype — тип выравнивания сегмента.
Определяет операции перемещения, которыемогут быть исполнены линкером. Ассемблер A51 допускает только один тип выравнивания – PAGE, который указывает, что начальный адрес сегмента должен бытьна границе 256-байтовой страницы памяти.BITбанкирегистровПримеры:DT BT ; объявление битового сегмента (BIT) в сегменте данных; (класс DATA)?PR? BA ; объявление переменной типа bitaddressable в; программном сегменте (класс CODE)?BA?file SEGMENT data bitaddressable ; объявление сегментаДиректива RSEGДиректива RSEG выбирает ранее объявленный директивой SEGMENT перемещаемыйсегмент.
Директива RSEG имеет следующий формат:RSEG SegNameгде SegName — имя сегмента, ранее объявленного директивой SEGMENT.Примеры:RSEG ?BA?fileV1: DS 1; резервирует число байтов переменнойMOV V1, #3 ; работа с целым байтомCLR 1.1 ; очистка бита26Директивы управления абсолютными сегментамиЭти директивы используют следующий формат:BSEGCSEGDSEGISEGXSEGATATATATATaddressaddressaddressaddressaddressопределяет абсолютный сегмент класса BITопределяет абсолютный сегмент класса CODEопределяет абсолютный сегмент класса DATAопределяет абсолютный сегмент класса IDATAопределяет абсолютный сегмент класса XDATAгде address — необязательный абсолютный базовый адрес, с которого начинается сегмент. Параметр address не может содержать ссылок вперед и должен быть выражением,которое результатом вычисления имеет допустимое значение адреса.2.6.2. Определение символов (назначение именам числовых значений)Директивы определения символов предоставляют вам возможность создавать символы,которые могут использоваться для представления регистров, чисел и адресов.
Символы,определяемые этими директивами не должны предварительно определяться и не должныпереопределяться. Только директива SET является исключением из этого правила.Директивы EQU и SETДирективы EQU и SET присваивают символическому имени SymName целочисленноезначение или символ регистра. Символы, определяемые EQU, не должны быть предварительно определены и не допускают переопределения. Директива SET допускает переопределение символов. Формат директив следующий:SymNameSymNameSymNameSymNameEQUEQUSETSETexpressionregisterexpressionregisterгдеexpression — целочисленное выражение (константное), не содержащее ссылок вперед,или простое перемещаемое выражение. Последнее содержит символы, определенные вперемещаемом сегменте; имена сегментов и внешние символы недопустимы в простыхперемещаемых выражениях.register — любое имя одного из регистров: A, B, R0R7, ...Символы, определенные директивами EQU и SET, могут использоваться везде: в операндах, выражениях, адресах.
Символы, определенные как регистры, могут использоватьсявезде, где допустим регистр. С помощью директивы EQU нельзя переопределять константны, а с помощью SET можно.Примеры:MOV A, #SymNameCnt EQU R7………………………DJNZ Cnt, Loop2.6.3. Директивы назначения адресовДирективы: BIT, CODE, DATA, IDATA, XDATA — присваивают значение адресауказанному символу SymName. Символы, определенные этими директивами, не могутбыть изменены или переопределены. Формат директив следующий:27SymNameBITbit_address; определяет BIT-символSymNameCODEcode_address; определяет CODE-символSymNameDATAdata_address; определяет DATA-символSymNameIDATAidata_address ; определяет IDATA-символSymNameXDATAxdata_address ; определяет XDATA-символгдеbit_address — адрес бита в области внутреннего ОЗУ (20H...2FH) с побитовойадресацией или адрес бита РСФ с побитовой адресацией.code_address — адрес кодовой памяти в диапазоне 0000H...0FFFFH.data_address — адрес прямоадресуемой ячейки внутреннего ОЗУ в диапазоне 0...127или адрес РСФ в диапазоне 128…255.idata_address — адрес косвенно адресуемой ячейки внутреннего ОЗУ в диапазоне0...255.xdata_address — адрес ячейки внешней памяти данных в диапазоне 0...65535.Кроме этих директив, имеются еще директивы аналогичного назначения sfr, sfr16, sbit,которые полностью совместимы с компилятором Cx51.
В результате предоставляетсявозможность использовать один общий файл определения РСФ как для ассемблера Ax51,так и для компилятора Cx51.Пример. Назначение переменной в фиксированный адрес:sfr sfr_sumbol = address_sfr (0x50-0xff)sbit sfr_bit_symbol = bit_address; 16 разрядов состоит из двух байт (к DPTR это не применимо)младшийAddrадрес мл.
байтаLH88старший16 разрядовsfr16 Adc_date = AddrAddr+1; Addr (L)2.6.4. Директивы инициализация кодовой памятиДирективы инициализации памяти используются для определения констант в кодовой памяти (ПЗУ). При этом инициализация памяти может выполняться байтами (директива DB)или словами (директива DW). Формат директив следующий:Label:Label:гдеDBDWexpression, expression ...expression, expression ...HLAddrAddr+1Label — символ, который задает адрес инициализируемой памяти.expression — байтовое значение для DB и шестнадцатиразрядное значение для DW.Каждое expression может быть символом, строкой символов или числовым значением,при этом выражение может быть любого типа.
Директивы DB и DW могут быть заданытолько в сегменте класса CODE, в противном случае будет выдано сообщение об ошибке.282.6.5. Директивы резервирования памятиЭти директивы используются для резервирования памяти под переменные. Началорезервирования соответствует текущему значению счетчика адреса в текущем активномсегменте.DBITДиректива DBIT резервирует пространство в битовом сегменте. Директива имеет следующий формат:Label:DBIT expressionгдеLabel — символ, задающий адрес резервируемой памяти. Этот символ имеет класс BIT.expression — число резервируемых битов. Выражение expression не может содержать ссылки вперед, перемещаемые или внешние символы.Директива DBIT резервирует пространство в битовом сегменте, начиная с текущего адреса.
Счетчик адреса для битового сегмента увеличивается на значение expression.DSДиректива DS резервирует заданное число байтов в сегментах памяти DATA, XDATA,IDATA. Директива имеет следующий формат:Label:DSexpressionгдеLabel — символ, задающий адрес резервируемой памяти. Символ Label — нетипизированное целочисленное значение – принимает значение текущего адреса и класс памятиактивного сегмента.expression — число резервируемых байтов. Выражение expression не может содержать ссылки вперед, перемещаемые или внешние символы.Директива DS резервирует пространство в текущем сегменте, начиная с текущего адреса.Затем текущий адрес увеличивается на значение expression.Примеры:X1X1:DS 4X2:DS 1 ; addr X2 = addr X1 + 4X3:DS 2 ; addr X3 = addr X2 + 1 = addr X1 + 5X1+1X1+2X1+3MOV R0, #X1 ; косвенная адресация – в регистр R0 значение X12.6.6. Директивы межмодульной связиЭти директивы делают возможным взаимодействие между независимо ассемблируемымимодулями, разрешая межмодульные связи и именование модулей.PUBLICЭта директива указывает список символов, которые могут быть использованы в другихобъектных модулях.