Программирование в среде IS-DOS 1993 г.

Элементы данных и выражения - набор знаков языка ассемблера. Символы языка ассемблера. Числа. Термы. Выражения.


3.ЭЛЕМЕНТЫ ДАННЫХ И ВЫРАЖЕНИЯ.

3.1.Набор знаков языка ассемблера.

Ассемблер работает с перечисленными ниже знаками символьных кодов ASCII и знаками альтернативной кодировки.

Знаки, используемые в символьных именах (символах) языка.

1.Латинские буквы и буквы кирилицы (кирилица допустима если не действует ключ /-r-us или директива .NRUS) .

2.Цифры от 0 до 9 (символ не может начинаться с цифры).
3.Знаки:

$ - знак денежной единицы (входит в символ только вместе с другими знаками);
[ - правая квадратная скобка;
] - левая квадратная скобка;
- обратная дробная черта;

- стрелка вверх;

- подчеркивание;

- знак фунта стерлингов.

4."." - точка, зарезервирована для использования в символах системных программ и библиотек.
Специальные знаки:

5.Знаки, используемые в термах выражений ассемблера.

- Цифры от 0 до 9 и буквы А В С D Е F; используются в числах,- *

$ - знак денежной единицы; представляет собой ссылку на программный счетчик адресов;

" - парные кавычки;индикатор символьного кода для двух или одного символа;

6.Разделительные и ограничительные знаки:

" "ДАВ - (коды 32 и 9) пробел и табулятор; необходимы как разделители между полями строки языка ассемблера;
в выражениях могут лишь отделять символьные имена друг от друга, а аргументы в поле операндов не отделяют,
и служат для выделения фрагментов текста для обеспечения лучшей читаемости программы;

, - запятая; необходима для отделения аргументов команд и директив в поле операндов;

<> - парные угловые скобки; используются в любом месте программы для выделения выражения, которое будет об-
рабатываться как терм;

: - двоеточие; необходимо для определения метки, если она отделена от начала строки пробелами или табулято-
рами;

7. Знаки операций.

В языке ассемблера допустимы унарные и бинарные операции. Унарные операции выполняются над одним термом(ар-
гументом или операндом). Унарная операция относится к тому терму, которому она предшествует.
+ - унарный плюс и бинарное сложение;
- - унарный минус и бинарное вычитание;
2~ - двойка и стрелка вверх; унарная операция возведения двойки в степень;

* - звездочка; арифметическое умножение;

/ - дробная черта; арифметическое деление;
& - коммерческое "И"; поразрядное логическое "И";
@ - коммерческое "ЭТ"; поразрядное логическое "ИЛИ";

! - восклицательный знак; поразрядное логическое исключающее "ИЛИ"( X0R );

8. Знаки временного изменения основания системы счисления числа.

% - процент; указатель двоичного числа;

# - решетка; указатель шестнадцатеричного числа;

9. Прочие знаки.

()- левая круглая скобка и правая круглая скобка; используются в аргументах команд Z80 для задания режима ад-
ресации и определения конкретной команды Z80 в соответствии со стандартом, принятым для мнемонического
обозначения команд Z80 .

3.2.Символы языка ассемблера.

Символы языка строятся из знаков, приведенных в п. 3.1., и об этом уже говорилось частично в п. 2.1.1...
В языке имеются символы двух типов: постоянные символы и символы, определяемые пользователем. Соответственно
этому ассемблер имеет таблицы символов трех типов:

PST - таблица постоянных символов,
UST - таблица символов пользователя

PST содержит все постоянные символы языка: мнемоники инструкций и регистров Z80, директив и команд ассемб-
лера. Эти символы не нуждаются в своем определении в программе, т.к. PST входит в сам транслятор.

Таблица UST заполняется при трансляции исходной программы в момент определения соответствующих символов и
построена по принципу бинарного дерева без оптимизации его ветвей-, что позволяет достичь хорошего быстродейс-
твия при трансляции. В связи с этим не рекомендуется располагать определяемые символы на протяжении достаточно
больших участков текста программы в строго алфавитном порядке (чтобы избежать вырождения бинарного дерева в
линейный список и замедления поиска).

Удобным способом избежать расположения меток в алфавитном порядке явилось бы применение локальных цифровых
символов типа 1$, 2$ и т.д., которые планируется реализовать во второй версии ассемблера.

Символы, определяемые пользователем, могут использоваться как метки, либо как константы, определяемые че-
рез директиву прямого присваивания EQU.

Кроме того, возможно их определение как глобальных или локальных символов, различающееся по области види-
мости.

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

Если в одном модуле будет определено несколько локальных символов с одинаковыми первыми 6 знаками, то это
вызовет ошибку 4. В этом случае верным будет считаться первое определение, однако, второй проход трансляции
будет блокирован и объектный код не будет создан.

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

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

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

3.3.Числа.

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

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

% - двоичное число. Переполнение свыше 16 цифровых знаков вызовет ошибку 44. При этом прекращается вычисле-
ние выражения, в котором стоит число, и его результат остается непредсказуемым.

# - шестнадцатиричное число. Переполнение свыше 16 цифровых знаков вызовет ошибку 44,как и в предидущем
случае, а свыше 4 знаков - ошибку 51. В последнем случае результат определится по младшим 4 цифровым знакам,
что соответствует двухбайтовому числу.

3.4.Термы.

Терм является компонентой выражения. Он может быть:

1.Числом (со значением в пределах 0-65536).

2.Символом; символы интерпретируются согласно следующим правилам:

- $ означает использование текущего счетчика адресов программы;

- символ, определенный пользователем, помещается в таблицу символов пользователя (UST);используется значение

символа из этой таблицы; это может быть метка, либо константа, определенная через директиву EQU;

- неопределенному символу, встретившемуся в поле операнда команды Z80 или директивы размещения блока данных

присваивается значение 0 и перемещаемость внешнего символа; если такой символ определен как локальный, то
он вызовет сообщение об ошибке 50.

- неопределенный символ, встретившийся в поле операнда директивы EQU, вызовет сообщение об ошибке 13 и прек-

ращение вычислений данного выражения, если на втором проходе потребовалось использование символа, стояще-
го в поле метки данной директивы EQU; значение такого символа и выражения с ним считается произвольным;

3.Одним либо двумя знаками в символьном коде ASCII или альтернативной кодировке, заключенными в кавычки,
например:"А","Яй" или "Ц";

4.Выражением, заключенным в угловые скобки; любая часть выражения, заключенная в угловые скобки обрабатывает-
ся прежде, остальной части; угловые скобки используются для изменения порядка слева направо обработки выраже-
ний (для отличия а+Ь*с от а+<Ь*с> )или для придания знака унарной операции всему выражению (например, -<а+Ь+с>
или 2~<а+Ь> ,где 2~-унарный оператор степени );

3.5.Выражения.

Выражение является комбинацией термов, разделенных знаками операций. Принята инфиксная форма записи выраже-
ния т.е. когда знаки операции располагаются между своими термами, а для нескольких следующих подряд унарных
операторов допускается префиксная запись, когда каждый унарный оператор действует на свой аргумент, стоящий
справа (см. примеры в ^гом же пункте). При нарушении такой формы записи возникает ошибка 33. Пробелы в выраже-
нии служат не обязательными разделителями термов, и их число не ограничено.

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

Выражения обрабатываются слева направо, за исключением унарных операций, которые имеют больший приоритет об-
работки, например, для унарного оператора 2~:

2+2~3*2 дает значение 20
2+8*2 дает значение 20

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

5*< 4+ < 3-<2@1> > > = 20

Глубина стека калькулятора ограничена 64 словами, что на практике вполне достаточно.
Запись подряд нескольких унарных операторов интерпретируется ассемблером как префиксная запись, например:

2+2~2~3 эквивалентно 2 + < 2~<2~3> > ,

что дает значение 258; здесь аргументами бинарного оператора "+" являются 2 и 2~2~3, аргументом первого унар-
ного 2~ - 2~3, а аргументом второго унарного оператора 2" будет число 3.

2+2~3~4 эквивалентно 2 + < 2~<3~4> >,

что вызовет ошибку 27, т.к. оператора 3" не существует в ассемблере.
-2~10+24 эквивалентно < -<2~10> > + 24 , что дает значение 1000;

Знаки + и - интерпретируются как знаки унарных операций только, если они стоят в начале терма, или выражения,
например:

в строке LD HL,-ABC-10 первый минус унарен и его аргументом является символ ABC, а второй минус бинарен и его
аргументы - это -ABC и 10;

в выражении 2~-<-АВС> первый минус бинарен, а второй унарен; поскольку перед бинарным минусом стоит оператор
2~, а не аргумент, то этим нарушается инфиксная скобочная форма записи выражений, что приведет к ошибке 33;
избежать ошибки можно, сделав первый минус унарным:

2~< -<-АВС> >

В выражениях можно использовать следующие знаки унарных операций (операторов):
+ унарный плюс, не меняет знака терма (+А есть само А);

- унарный минус, меняет знак терма (-А есть противоположное значение А в дополнительном коде), например: -1

есть 65535 ;

2~ степень двойки, возводит число два в степень, заданную значением терма, например, 2~10 есть 1024.

и следующие бинарные операторы:
+ сложение;

- вычитание;

& поразрядное логическое "и";
@ поразрядное логическое "или";
! поразрядное логическое исключающее "или";
* умножение;

/ деление; результат целый;
? функция MOD: А?В=А-< <А/В>*В >

Примеры выражений, при условии, что stepl равна 0, step2 равна 1, а $МЕТ не определена :

выражение результат

2~stepl @ 2~step2 3

#1234?256+<#1234/256*256> #1234

-<1+2*3-4> -5

+ 1 26
%1000000001 ! 65535 %1111110111111110

"ab"&<2~5*256+2~5!65535> "АВ"

#100-$МЕТ*2 О

В последнем примере результат выражения временно полагается равным 0 до его корректировки компоновщиком.

Все вычисления ведутся в двоичном дополнительном 16 разрядном коде. Поэтому значение выражения не может
превосходить 16-разрядной величины.

Предупреждения об ошибках переполнения возникают только, в операции умножения, если переполнение может при-
вести к неверному знаку результата (при превышении результата умножения двух соответствующих положительных ве-
личин значения 32767= =#7FFF).(см.пример в описании ошибки 15). Возникновение ошибки переполнения в аналогич-
ной ситуации при сложении и вычитании (изменение знака) не идентифицируется, т.к. дополнительная кодировка га-
рантирует верность 16 младших разрядов результата этих операций, как в интерпретации чисел без знака , так и в
знаковой их интерпретации. Но при комбинировании сложения и вычитания с делением следует соблюдать осторож-
ность, т.к. деление предполагает только знаковую интерпретацию чисел (когда числа > 32767 интерпретируются как
отрицательные ) . Например:
#1+#FFFF-#FFFE = #10000-#FFFE = 2 ,

в беззнаковой интерпретации,но в знаковой будет то же самое:
1+ <-1>- <-2> = 0- <-2> = 2

в связи с этим бывает полезно иметь возможность определять знак терма, чтобы правильно использовать операции
деления и умножения. Такая возможность есть в ассемблере. Побочным эффектом деления на ноль является вычисле-
ние некой обратной знаковой функции:

А/0= -1 для А >= 0
А/0= +1 для А < 0

Воспользовавшись этим, можно, например, корректно работать с неким адресом буфера $BUF при вычислении его
старшего байта $HBUF, не зависимо от конкретного значения (знака числа $BUF):

$HBUF EQU <$BUF-#8000/256+#80>*
*<$BUF/0+l/2> + <$BUF/256*<-$BUF/0+l/2>>
;для $В11Ротриц. для $BUF полож.

На самом деле выражение должно быть записано в одну строку.

Здесь терм <$BUF/0+l/2> равен 0 для $BUF<=#7FFF, и он равен 1 при $BUF>#7FFF, а для терма <-$BUF/0+l/2> все
будет как раз наоборот. В результате, используя данные термы в качестве сомножителей, можно вычислять $HBUF по
разным формулам для положительных и отрицательных значений $BUF.

3.5.1.Перемещаемость при вычислении выражений.

Вычисление выражения включает определение его перемещаемости, т.е. зависимости его значения от изменения ад-
реса компоновки (и загрузки) модуля, в которое входит данное выражение.
Результирующее значение выражения может быть любым из четырех типов, описываемых ниже абсолютным, относитель-
ным, внешним или сложным относительным.

Выражение (и его значение) является абсолютным,если его значение фиксировано, не зависит от адреса компонов-
ки.

Следующие выражения имеют абсолютные значения:

- выражения, термы которых являются числами или знаками символьного кода;

- относительное выражение или терм минус относительный терм, поскольку такое выражение преобразуется ассемб-
лером к концу анализа выражения в единичный терм - абсолютное число;

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

Например, в следующем фрагменте, значения выражения МЕТ2-МЕТ1 и значение аргумента команды короткого безус-
ловного перехода будут абсолютными:

адр код стр текст программы
О 18 3 1 JR MED2

2 2 МЕТ1

2 21 3 0 3 LD HL,МЕТ2-МЕТ1

5 4 МЕТ2

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

- выражения, состоящие из одного простого терма-метки или терма-символа программного счетчика адресов.

- относительное выражение плюс (минус) абсолютный терм.

Значения таких выражений, выводимые в листинге в поле кода,помечаются знаком г.

Информация о них занимает дополнительно к 1 или 2 байтам, индицируемым в поле кода листинга, еще 2 байта.

адр код стр текст программы
О ООО 1 Ml DEFS 160
АО 21 0 Ог 2 М2 LD HL,M1
A3 11 А6 Or 3 LD DE,МЗ+<М2-М1>

A6 ООО 4 МЗ DEFS М2-М1

Выражение является сложным относительным, если выполняется одно из следующих условий:

- величина, получаемая в результате вычисления выражения,требует более, чем одно перемещение; например, если
относительные термы МЕТ1 и МЕТ2 образуют выражение вида МЕТ1+МЕТ2, то будут выполнены два перемещения ком-
поновщиком, (т.е. к значению выражения будет добавлен адрес компоновки модуля два раза );

- перемещение должно быть выполнено с обратным знаком, т.е. значение адреса компоновки модуля должно вычи-
таться, из значения выражения один или несколько раз, например -МЕТ1, где МЕТ1 - относительный терм;

Значения таких выражений, выводимые в листинге в поле кода,помечаются знаком т, и им временно присваивается
нулевое значение до окончательной обработки их компоновщиком. Информация о них занимает дополнительно к 1 или
2 байтам, индицируемым в поле кода листинга, еще 6 байт.

Выражение является внешним в следующих случаях:

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

символ в другом модуле);

- операция, отличная от сложения, вычитания или изменения знака, применяется к относительной величине.

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

Такие выражения не могут быть вычислены ассемблером и записываются в объектный файл в постфиксной форме для
передачи компоновщику, практически целиком. Если же левые термы выражения не являются внешними, то они буду!
вычислены и выражение запишется в объектный файл в укороченном виде (это не касается выражений с неопределены-
ми символами). Например, следующее выражение будет частично вычислено ассемблером: LENG2-LENG1+BUFF/256 , где
LENG1 и LENG2 - относительные термы; а это запишется в объектный файл целиком:

BUFF/256+LENG2-LENG1 ,

т.к. терм <LENG2-LENG1> не является внешним (он абсолютный) и, поэтому, может быть вычислен, если стоит в вы-
ражении слева.

3.6.Программный счетчик адресов.

Символ $ зарезервирован для использования в качестве идентификатора текущего счетчика адресов в программе
на ассемблере.

В начале каждого прохода его значение полагается равным нулю. После трансляции любого оператора ассемблер-
ной строки он получает значение, равное сумме предыдущего и длины оттранслированного оператора (команды Z80
или блока данных). Кроме того, в директивах DEFB и DEFW, он получает соответствующее приращение при трансляции
каждого аргумента этих директив.

Таким образом, при использовании этого символа в поле операнда инструкции Z80 он обозначает адрес первого
байта инструкции. При использовании его в поле операнда директивы ассемблера он представляет адрес текущего
байта, слова или блока данных (в директиве DEFS).




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Coding - приемы оптимизации кода.
Beatles - Сегодня у нас самая известная песня гpуппы "Евpопа" - "Последний отсчет".
Вступление - Наконец-то я сделал это! Я собрал в кучу ПЕРВУЮ в истории GOMEL-NET тусовку!
Мозаика - подключение DENDY'евского видеопроцессора к ZX Spectrum.
От редакции - Приглашаем вас, дорогие читатели, в мир творчества, в мир Спектрума.

В этот день...   28 апреля