Директивы ассемблера
Директивы управления модулями
Директивы управления модулями используются чтобы отметить начало и конец модулей исходной программы, и для того чтобы назначить имена и типы к ним. Эти директивы приведены в таблице 1.
Таблица 1 - Директивы управления модулями
|
Директива |
Описание |
|
END |
Заканчивает трансляцию последнего модуля в файле. |
|
ENDMOD |
Заканчивает трансляцию текущего модуля. |
|
LIBRARY |
Начинает библиотечный модуль |
|
MODULE |
Начинает библиотечный модуль |
|
NAME |
Начинает модуль программы. |
|
PROGRAM |
Начинает модуль программы. |
|
RTMODEL |
Объявляет атрибуты модуля во время выполнения. |
Синтаксис:
END [label]
ENDMOD [label]
LIBRARY symbol [(expr)]
MODULE symbol [(expr)]
NAME symbol [(expr)]
PROGRAM symbol [(expr)]
RTMODEL key, value
где:
expr необязательный параметр, принимает значение от 0 до 255, используется компилятором iar для определения языка программирования, модели памяти и конфигурации процессора.
key текстовая строка, определяющая ключ.
label метка или выражение, значение которого подсчитывается при трансляции. в объектном коде заменяется на адрес программы.
symbol имя модуля, используется xlink и xlib.
value текстовая строка, определяющая значение.
Описание директив управления модулями
NAME
Используется чтобы начать модуль программы и назначать имя для будущей ссылки для IAR XLINK Linker™ и IAR XLIB Librarian™. Модули программы безоговорочно связаны XLINK, даже если другие модули не ссылаются на них.
MODULE
Используется чтобы создать библиотеки, содержащие много маленьких подобных модулям систем поддержки для языков высокого уровня - где каждый модуль часто представляет отдельную подпрограмму. При использовании мультимодульного программирования, можно значительно уменьшить число источников и необходимых объектных файлов. Библиотечные модули только скопированы в связанный код, если другие модули ссылаются на общую символьную метку в модуле.
ENDMOD
Используется для определения конца модуля.
END
Используется чтобы указать конец исходного файла. Любые строки после директивы END игнорируются.
RTMODEL
Используйтся чтобы предписать последовательность между модулями. Все модули, которые связаны вместе должны быть определены одинаковыми ключами атрибутов , или специальным значением *. Использование специального значения * эквивалентно, что атрибуты неопределенны вообще. Бывает полезно явно заявить, что модуль может обработать любую модель во время выполнения. Атрибуты модели компилятора начинаются с двойного подчеркивания. Чтобы избежать беспорядка, этот стиль не должен использоваться в определяемых пользователем атрибутах ассемблера.
Примеры:
Следующий пример определяет три модуля, где:
MOD_1 и MOD_2 не могут быть связаы вместе, так как они имеют различные значения для модели "foo"
MOD_1 и MOD_3 могут быть связаны вместе, так как они имеют одинаковое определение модели "bar" и никакого конфликта в определении "foo".
MOD_2 и MOD_3 могут быть связаны вместе, так как они не имеют никаких модельных конфликтов . Значение "*" соответствует любому модельному значению.
MODULE MOD_1
RTMODEL "foo", "1"
RTMODEL "bar", "XXX"
...
ENDMOD
MODULE MOD_2
RTMODEL "foo", "2"
RTMODEL "bar", "*"
...
ENDMOD
MODULE MOD_3
RTMODEL "bar", "XXX"
...
END
Директивы управления символическими определениями (переменными)
Данные директивы управляют символическими определениями между модулями. Эти директивы приведены в таблице 2.
Таблица 2 - Директивы управления символическими определениями
|
Директива |
Описание |
|
EXTERN (IMPORT) |
Импортирует внешнее символическое определение. |
|
PUBLIC (EXPORT) |
Экспортирует символические определения другим модулям |
|
PUBWEAK |
Экспортирует символические определения другим модулям. Позволяет многократные определения. |
|
REQUIRE |
Вынуждает символическое определение быть упомянутым. |
Синтаксис: EXTERN symbol [:SADDR] [,symbol[:SADDR]] …
PUBLIC symbol [,symbol] …
PUBWEAK symbol [,symbol] …
REQUIRE symbol
Где: symbol – символическое определение, которе необходимо экспортировать/импортировать
Описание директив управления символическими определениями.
PUBLIC
Используется для того, чтобы сделать один или более символических определений доступными другим модулям. Символическим определениям (переменным) объявленным как PUBLIC могут быть присвоены только значения (константы). При этом далее при написании кода программы можно использовать эти переменные. Символические определения объявленным директивой PUBLIC, могут быть изменяемыми или абсолютным, и могут также использоваться в выражениях (с теми же самыми правилами, что и для других символических определений). Директива всегда экспортирует полные 32-битные значения что, делает доступным использование глобальных 32-разрядных констант также в ассемблерах и для 16 и 8 – разрядных процессоров. С помощью операторов LOW, HIGH, >>, and , << любая часть 32-разрядной константы может быть загружена в 8 или 16 – разрядный регистр. На число переменных, объявленных директивой PUBLIC нет никаких ограничений.
EXTERN
Используется, чтобы импортировать невведённую внешнюю переменную. Для того чтобы указать, что она расположена в коротком адресном пространстве, используется суффикс :SADDR.
Примеры:
Следующий пример определяет подпрограмму, которая выводит сообщения об ошибках, и экспортирует адрес ошибки err так, чтобы можно было вызвать его из других модулей. print определяется как внешняя подпрограмма; адрес будет вычислен во время компоновки.
NAME error
EXTERN print
PUBLIC err
err CALL print
DC8 "** Error **"
EVEN
RET
END
Директивы управления сегментами.
Директивы управления сегментом могут быть использованы для того, чтобы поставить в соответствие символическим именам определённые числовые значения, регистры процессора и сегменты. Эти директивы требуют, чтобы имя символа было определено наряду с адресом, числовым значением, регистром или типом сегмента. Директивы приведены в таблице 3.
Таблица 3 – Директиы управления сегментами
|
Директива |
Описание |
|
ALIGN |
Выравнивает счетчик адреса, вставляя нулевые байты. |
|
ALIGNRAM |
Выравнивает счетчик адреса, увеличивая его (никакого заполнения). |
|
ASEG |
Начало абсолютного сегмента |
|
ASEGN |
Начало названного абсолютного сегмента |
|
COMMON |
Начало общего сегмента |
|
EVEN |
Выравнивает счетчик программ к четному адресу. |
|
ORG |
Устанавливает счетчик адреса. |
|
RSEG |
Начало перемещаемого сегмента |
|
SADDR |
Начало перемещаемого сегмента с коротким адресом |
|
SHORTAD |
Начало перемещаемого сегмента с коротким адресом (предусмотрена обратная совместимость) |
|
STACK |
Начало сегмента стека |
Синтаксис: ALIGN align [,value]
ALIGNRAM align [,value]
ASEG [start [(align)]]
ASEGN segment [:type], address
COMMON segment [:type] [(align)]
EVEN [value]
ORG expr
RSEG segment [:type] [flag] [(align)]
RSEG segment [:type], address
SADDR [(align)]
SHORTAD [(align)]
STACK segment [:type] [(align)]
где:
expr - значение адреса, в которое необходимо установить счетчик адреса.
segment - символическое имя сегмента.
start - начальный адрес, используется аналогично директиве ORG в начале абсолютного сегмента.
type - тип памяти (UNTYPED, CODE или DATA)
value - Значение байта, используемое для дополнения, значение по умолчанию является нулевым.
address – Адрес, куда будет помещён сегмент
align - Экспонента значения, к которому адрес должен быть выравнен, в диапазоне от 0 до 30.
flag – может иметь следующие параметры:
NOROOT
Эта часть сегмента может быть отвергнута компоновщиком, даже если никакие символические определения в этой части доли не упомянуты. Обычно все части сегмента (кроме кода запуска и векторов прерывания) должны установить этот флаг. Заданный по умолчанию режим - ROOT,указывает, что часть сегмента не должна быть отвергнута.
REORDER
Позволяет компоновщику переупорядочивать части сегмента. Для данного сегмента, все части сегмента должны определить то же самое состояние этого флажка. NOREORDER – указывает, что все части сегмента должны оставаться на своих местах
SORT
Компоновщик сортирует части сегмента в уменьшающемся порядке выравнивания. Для данной доли, все части доли должны определить то же самое состояние для этого флажка. NOSORT – указывает, что части не нужно сортировать (по умолчанию)
Описание директив управления сегментами
ASEG
Используется, чтобы установить абсолютный режим трансляции, который является значением по умолчанию в начале. Если параметр опущен, адрес начала первого сегмента - 0, и последующие сигменты продолжаются после последнего адреса предыдущей сегмента.
ASEGN
Используется, чтобы запустить названный абсолютный сегмент, расположенный с адреса address. Эта директива имеет преимущество разрешения самостоятельно определить тип памяти сегмента.
RSEG
Используется, чтобы установить текущий режим трансляции как к перемещаемому режиму трансляции. Ассемблер поддерживает отдельные счетчики адреса (первоначально установленный на нуль) для всех сегментов, который позволяет переключать сегменты и их режим в любое время без необходимости сохранять текущий счетчик адреса сегмента. В отдельном модуле может быть определено до 65536 уникальных перемещаемых сегментов.
STACK
Используется, чтобы распределить код или данные от старших к младшим адресам (в отличие от директивы RSEG, которая использует распределение низкое-к-высокому ). Содержимое сегмента не генерируется в обратном порядке.
COMMON
Используется , чтобы разместить данные в память в том же самом местоположении как и сегменты директивы COMMON других модулей, которые имеют то же самое название. Другими словами, все сегменты с тем же именем быдут запускаться в том же самом местоположении памяти и переключаются странично. Очевидно, тип сегмента COMMON не должен использоваться для выполняемого кода с оверлеем. Типичные программы удобно писать, когда множество различных подпрограмм совместно бы использовало общую область памяти для данных. Практично иметь таблицу векторов прерываний в ОБЩЕМ (COMMON) сегменте, таким образом появляется доступ нескольких подпрограмм к данной таблице. Использование параметра align в любой из вышеупомянутых директив, необходимо для выравнивания адреса запуска сегмента.
ORG
Используется, чтобы установить счетчик адреса программы текущго сегмента к значению выражения. Дополнительная метка примет значение и тип нового счетчика адреса. Результат выражения должен иметь тот же самый тип что и текущий сегмент, то есть не следует использовать ORG 10 для RSEG, так как выражение абсолютно; Правильно записывается ORG $+10. Выражение не должно содержать никаких внешних ссылок. Все счетчики адреса программы установлены на нуль в начале трансляции сегмента.
ALIGN
Используется, чтобы выровнять счетчик адреса программы к указанной границе адреса. Выравнивание сделано относительно начала доли. ALIGN выравнивается обнулением/заполнением байтов. Директива EVEN выравнивает программу в по четному адресу (который является эквивалентным ALIGN 1), а директива ODD выравнивает программу по нечетному адресу.
SADDR
Директива определяет, что метки, определенные в перемещаемом сегменте будут принадлежать короткой области адреса. директива SADDR - в действительна, пока следующий семент не управляет ей.
Примеры:
Начало абсолютного сегмента:
Следующий пример транслирует команды входа подпрограммы прерывания в соответствующих векторах прерывания, используя абсолютный сегмент.
EXTERN intnmi,intwdt,intp0,intp1
ASEG
ORG 0x0
DC16 main ; RESET_vect
int0 DC16 intnmi
int1 DC16 intwdt
int2 DC16 intp0
int3 DC16 intp1
ORG 0x2100
main MOVW AX,[SP+2] ; Start of code
END
Начало перемещаемого сегмента:
В следующем примере, данные после первой директивы RSEG помещены в перемещаемый сегмент названный table; директива ORG используется чтобы создать промежуток шести байтов в таблице. Код, после второй директивы RSEG помещен в перемещаемый сегмент, названный code
EXTERN divrtn,mulrtn
RSEG table
DC16 divrtn,mulrtn
ORG $+6
DC16 subrtn
RSEG code
subrtn MOV A,R7
SUB A,#20
END
Начало стекового сегмента:
Следующий пример определяет два 100-байтовых стека в перемещаемом сегменте, названным rpnstack
STACK rpnstack
parms DS8 100
opers DS8 100
END
Начало общего сегмента:
Следующий пример определяет два общих сегмента, содержащих переменные:
NAME common1
COMMON data
count DC32 1
ENDMOD
NAME common2
COMMON data
up DC8 1
ORG $+2
down DC8 1
END
Поскольку общие сегменты имеют одинаковые имена , data, переменные up и down относятся к одним и тем же местоположениям в памяти как первые и последние байты 4-х байтовой переменной count.
Выравнивание сегмента:
Этот пример начинает перемещаемый сегмент, перемещается в четный адрес, и добавляет некоторые данные. Тогда сегмент выравнивается к 64-байтовой границе перед созданием 64-байтовой таблицы.
NAME align
RSEG data ; Запуск перемещаемого сегмента data
EVEN ; Гарантирование, что он находится на чётной границе адреса
target DC16 1 ; Цель находится на чётной границе
ALIGN 6 ; Заполнение нулями, до 64-байтной границы
results DS8 64 ; Создание 64-байтовой таблицы
ALIGNRAM 3; Выравнивание к 8-ми байтовой границе
ages DS8 64 ; Создание другой 64-байтовой таблицы
END
Использование директивы SADDR
Следующий пример демонстрирует, как объявленная метка sad1, относится к SADDR области:
RSEG sdata
SADDR
sad1 DC8 1
RSEG code
MOV A,sad1
END
Условные директивы трансляции
Эти директивы обеспечивают логический контроль над выборочной трансляцией исходного текста. Директивы приведены в таблице 4.
Таблица 4 - Условные директивы трансляции
|
Директива |
Описание |
|
ELSE |
Транслирует команды, если условие является ложным. |
|
ELSEIF |
Определяет новое условие для блока IF … ENDIF |
|
ENDIF |
Заканчивает IF – блок |
|
IF |
Транслирует команды, если условие истинно. |
Синтаксис: ELSE
ELSEIF condition
ENDIF
IF condition
Где: параметр condition принимает одно из следующих значений:
Абсолютное выражение
Выражение не должно содержать внешние ссылки, и любое ненулевое значение рассматривают как истина.
string1=string2
Условие истинно, если string1 и string2 имеют одинаковую длину и содержание.
string1<>string2
Условие истинно, если string1 и string2 имеют разную длину и содержание.
Описание условных директив трансляции
IF, ELSE,ENDIF
Директивы IF, ELSE, и ENDIF используются, для управления процессом трансляции кода во время ассемблирования. Если состояние после IF директивы не истинно, последующие команды не будут обработаны , пока не будут найдены директивы ELSE или ENDIF.
ELSEIF
Директива ELSEIF используется , для ввода нового условия после директивы IF. Условные директивы ассемблера могут использоваться хоть где в коде.
Все директивы ассемблера (кроме END) могут быть заблокированы условными директивами.
Каждая директива IF должна быть закончена директивой ENDIF . Директива ELSE является дополнительной, и если используется, то должна быть заключена в блок IF ... ENDIF . блоки IF ... ENDIF и IF ... ELSE ...ENDIF могут иметь многоуровневые вложения.
Примеры:
Следующая макрокоманда добавляет константу в регистр:
addm MACRO a,b
IF ’b’=’1’
INC a
ELSE
ADD a,#b
ENDIF
ENDM
Если аргумент b макрокоманды равен 1, то выполняется команда INC , для сохранения циклов счётчика; иначе выполняется команда ADD.
Это может быть проверено следующей программой:
main MOV R0,#17
addm R0,2
MOV R1,#22
addm R1,1
RET
END
Директивы макрообработки
Эти директивы позволяют создавать пользовательские макроопределения (макрокоманды). Директивы приведены в таблице 5.
Таблица 5 – Директивы макрообработки
|
Директива |
Описание |
|
_args |
Установливает число аргументов для макроса. |
|
ENDM (ENDMAC) |
Конец макрокоманды |
|
ENDR |
Конец повторной структуры |
|
EXITM |
Преждевременный выход из макроса |
|
LOCAL |
Создает локальные переменные макроса. |
|
MACRO |
Определяет макрос (начало макроса) |
|
REPT |
Собирает инструкции указанное количество раз. |
|
REPTC |
Повторения и характеристики символов. |
|
REPTI |
Повторения и характеристики строк. |
Синтаксис: ENDM
ENDR
EXITM
LOCAL symbol [,symbol] …
name MACRO [,argument] …
REPT expr
REPTC formal,actual
REPTI formal,actual [,actual] …
где: actual - строка, которая будет заменена.
argument – имя символического аргумента.
expr – выражение.
formal – параметр, который заменяется actual
name – имя макрокоманды
symbol – локальная переменная макрокоманды
Описание директив макрообработки
Макрокоманда - определяемый пользователем символическое выражение, который представляет блок одной или более строк исходного кода ассемблера. Как только Вы определили макрокоманду, Вы можете использовать её в вашей программе подобно директиве ассемблера или мнемонической команде ассемблера.
Когда ассемблер сталкивается с макрокомандой, то ищет определение макрокоманды, и вставляет строки, которые макрокоманда представляет, как будто они были включены в исходный код в той позиции, где макрокоманда вызывается.
Макрос фактически исполняет простую текстовую замену, и Вы можете управлять тем, что они заменяют, изменяя их параметры.
Определение макроса:
macroname MACRO [,arg] [,arg] …
Здесь, macroname - имя, которое Вы собираетесь использовать для макрокоманды, и arg - параметр для аргумента, которые Вы хотите передать макрокоманде, когда макрокоманда расширена.
Например, можно определить макрокоманду ERROR следующим образом:
errmac MACRO text
CALL abort
DC8 text,0
ENDM
Эта макрокоманда использует параметр text, чтобы установить сообщение об ошибках для подпрограммы abort. Вы вызвали бы макрокоманду инструкцией типа:
errmac 'Disk not ready'
Таким образом можно выводить сообщение об ошибках, просто вызывая макрокоманду с описанием текста ошибки. Ассемблер транслирует это как:
CALL abort
DC8 'Disk not ready',0
EXITM
Используется для преждевременного выхода из макрокоманды.
EXITM не может находиться внутри блоков REPT ... ENDR, REPTC .. .ENDR, или REPTI .. .ENDR.
LOCAL
Используeтся для создания локальных переменных макрокоманды. Директива LOCAL должна использоваться прежде, чем используется переменная. Каждый раз, когда макрокоманда расширена, новые локальные переменные должны быть созданы директивой LOCAL . Поэтому, следует использовать локальные переменные в рекурсивном макросе.
Предопределённые макро-переменные
Символ _args установливает число аргументов, прошедших к макрокоманде. Следующий пример показывает, как может использоваться _args :
MODULE A78K0_MAN
EXTERN sub1
MACRO DO_SUB1
IF _args == 2
CMP \0, \1
BZ nocall
CALL sub1
nocall:
ELSE
CALL sub1
ENDIF
ENDM
RSEG CODE
DO_SUB1
DO_SUB1 A, #2
END
Будет сгенерирован следующий листинг программы:
1 0000 MODULE A78K0_MAN
2 0000 EXTERN sub1
13 0000
14 0000 RSEG CODE
15 0000
16 0000 DO_SUB1
16.1 0000 IF _args == 2
16.2 0000 CMP ,
16.3 0000 BZ nocall
16.4 0000 CALL sub1
16.5 0000 nocall:
16.6 0000 ELSE
16.7 0000 9A.... CALL sub1
16.8 0003 ENDIF
16.9 0003 ENDM
17 0003 DO_SUB1 A, #2
17.1 0003 IF _args == 2
17.2 0003 4D02 CMP A, #2
17.3 0005 AD03 BZ nocall
17.4 0007 9A.... CALL sub1
17.5 000A nocall:
17.6 000A ELSE
17.7 000A CALL sub1
17.8 000A ENDIF
17.9 000A ENDM
18 000A
19 000A END
Введение специальных символов.
Макро параметры, которые включают запятые или незаполненное пространство, могут интерпретироваться как один параметр, используя символы кавычки соответствия < и > в макро запросе. Например:
macld MACRO op
MOV op
ENDM
macld <A, #1>
END
Вы можете переопределить макро символы кавычки опцией -M , командной строки.
Обработка макрокоманд ассемблером.
Макро команды обрабатываются ассемблером в 3 фазы:
1) Ассемблер исполняет поиск и сохранение макроопределений. Текст между MACRO и ENDM сохраненяется, но синтаксис не проверяется. Ссылки файла включения $file записаны и будут включены в течение макрорасширения.
2) Макро запрос вынуждает ассемблер вызывать макропроцессор (расширитель). Макро выключатели расширителя (если уже не в макрокоманде) ассемблер вводит поток из исходного файла до вывода с макро расширителя. Макро расширитель берет его ввод из требуемого макроопределения. Макро расширитель не имеет каких-либо сведений о синтаксисе символов ассемблера, так как он только имеет дело с текстовыми заменами на исходном уровне. Прежде, чем строка из вызванного макроопределения передана ассемблеру, расширитель просматривает строку для всех возникновений символических макро параметров, и заменяет их с их параметрами расширения.
3) Расширенная строка тогда обрабатывается как любая другая строка исходного кода ассемблера. Входной поток к ассемблеру продолжит вывод от макропроцессора, пока все строки текущего макроопределения не прочитались.
Повторение инструкций, входящих в макрокоманду
Структура REPT ... ENDR используется для трансляции того же самого блока команд заданное число раз. Если параметр expr равен нулю, обработка команд производиться не будет.
Директива REPTC используется, чтобы транслировать блок команд один раз для каждого символа в строке. Если строка содержит запятую, то строка должна быть заключена в кавычки.
Двойные кавычки имеют специальное значение, единственное где они могут использоваться - это при итерациях. Одинарные кавычки кавычки не имеют никакого специального значения и обрабатываются, как и любой обычный символ.
Директива REPTI используется , чтобы транслировать блок команд однажды для каждой строки в ряде строк. Строки, содержащие запятые должны быть включены в кавычки
Примеры:
Приведём примеры, где макрокоманды намного упрощают программирование на языке ассемблера.
В коде часто необходимо вызывать подпрограммы, при этом используется вызов подпрограммы и возвращение, что может вызвать переполнение. Этого необходимо избегать. Макрос обеспечивает удобный способ сделать это.
Следующий пример выводит байты c буфера в порт:
NAME play
sfr P0=0xFF00
RSEG DATA
buffer DS8 25
watch DC8 0xFF
RSEG CODE
play MOVW AX,#buffer
MOVW HL,AX
MOV B,#0
MOV A,[HL+B]
loop INC B
MOV P0, A
MOV A,[HL+B]
CMP A,watch
BNZ loop
RET
END
Основная программа вызывает эту подпрограмму следующим образом:
doplay CALL play
Для эффективности можно повторно написать код с использованием макрокоманды:
NAME play
ORG 0
DC16 main
play MACRO
LOCAL loop
MOVW AX,#buffer
MOVW HL,AX
MOV B,#0
MOV A,[HL+B]
loop INC B
MOV P0, A
MOV A,[HL+B]
CMP A,watch
BNZ loop
ENDM
sfr P0=0xFF00
RSEG DATA
buffer DS8 25
watch DC8 0xFF
RSEG CODE
main play
play
RET
END
Обратите внимание на использование директивы LOCAL , которая делает метку loop местной в макрокоманде; иначе будет ошибка , если макрокоманда используется дважды, поскольку метка loop уже будет существовать.
Использование директив REPTI и REPTC
Следующий пример транслирует ряд запросов к подпрограмме plot, чтобы составить график каждого символа в строке:
NAME reptc
EXTERN plotc
sfr P0=0xFF00
banner REPTC chr,"Welcome"
MOV P0,#’chr’
CALL plotc
ENDR
END
В результате получается следующий код:
1 000000 NAME reptc
2 000000
3 000000 EXTERN plotc
4 000000 sfr P0=0xFF00
5 000000 banner REPTC chr,"Welcome"
6 000000 MOV P0,#'chr'
7 000000 CALL plotc
8 000000 ENDR
8.1 000000 130057 MOV P0,#'W'
8.2 000003 9A.... CALL plotc
8.3 000006 130065 MOV P0,#'e'
8.4 000009 9A.... CALL plotc
8.5 00000C 13006C MOV P0,#'l'
8.6 00000F 9A.... CALL plotc
8.7 000012 130063 MOV P0,#'c'
8.8 000015 9A.... CALL plotc
8.9 000018 13006F MOV P0,#'o'
8.10 00001B 9A.... CALL plotc
8.11 00001E 13006D MOV P0,#'m'
8.12 000021 9A.... CALL plotc
8.13 000024 130065 MOV P0,#'e'
8.14 000027 9A.... CALL plotc
9 00002A
10 00002A END
Следующий пример использует REPTI, чтобы очистить множество ячеек памяти:
NAME repti
EXTERN base,count,init
MOV A, #0
banner REPTI adds,base,count,init
MOV adds, A
ENDR
END
В результате будет получен следующий код:
1 000000
2 000000 NAME repti
3 000000
4 000000 EXTERN base,count,init
5 000000
6 000000 A100 MOV A, #0
7 000002 clear REPTI adds,base,count,init
8 000002 MOV adds, A
9 000002 ENDR
9.1 000002 9E.... MOV base, A
9.2 000005 9E.... MOV count, A
9.3 000008 9E.... MOV init, A
10 00000B
11 00000B END
