Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
88
Добавлен:
12.03.2015
Размер:
320 Кб
Скачать
  1. Директивы ассемблера

    1. Директивы управления модулями

Директивы управления модулями используются чтобы отметить начало и конец модулей исходной программы, и для того чтобы назначить имена и типы к ним. Эти директивы приведены в таблице 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

    1. Директивы управления символическими определениями (переменными)

Данные директивы управляют символическими определениями между модулями. Эти директивы приведены в таблице 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

    1. Директивы управления сегментами.

Директивы управления сегментом могут быть использованы для того, чтобы поставить в соответствие символическим именам определённые числовые значения, регистры процессора и сегменты. Эти директивы требуют, чтобы имя символа было определено наряду с адресом, числовым значением, регистром или типом сегмента. Директивы приведены в таблице 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

    1. Условные директивы трансляции

Эти директивы обеспечивают логический контроль над выборочной трансляцией исходного текста. Директивы приведены в таблице 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

    1. Директивы макрообработки

Эти директивы позволяют создавать пользовательские макроопределения (макрокоманды). Директивы приведены в таблице 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

Соседние файлы в папке методички к 78К0