Для языков ассемблера в дополнение к общей семантике элементарного уровня яну характерно наличие команд над вещественными числами и обработки кодов
Скачать 226.07 Kb.
|
59 расположенных в памяти (вектора, строки, стеки, очереди, файлы). Можно рассчитывать, что так определена базовая часть учебного концентра (элементарного уровня) любого ЯП. Другие вспомогательные семантики языков ассемблера, макропроцессора, вычислений над стеком и управления процессами, машинно-зависимых и машинно-независимых машинно- ориентированных ЯП могут рассматриваться как расширения такой базовой части. Здесь не рассмотрены СУБД, языки работы с сайтами и ряд других средств создания распределѐнных систем. 3.1. Императивное программирование на ассемблере Обработка данных с помощью программ, представленных на языке ассемблера, сводится к императивной машинно-ориентированной модели управления процессом выполнения действий, порожденных программой. В центре внимания – конфигурация оборудования, состояние памяти, система команд, передачи управления, очередность событий, исключения и неожиданности, время реакции устройств и успешность процессов обработки информации, нацеленных на свободный доступ к любым возможностям оборудования. Кодирование алгоритма осуществляется на фоне применения дополнительных средств, таких как блок-схемы и документирование, отчасти компенсирующих отсутствие в языке ассемблера понятий уровня программистской фразеологии, а в естественных языках – понятий, возникающих при такой «сверхточной» детализации программ на языке ассемблера. Результативность представления программ обеспечивает макротехника или автоматный подход к реализации алгоритмов – методика автоматного программирования, поддерживающая выделение шагов модели программы независимо от базовых средств ЯНУ. Автоматное программирование возникло до появления ЯВУ. Для языков ассемблера в дополнение к общей семантике элементарного уровня ЯНУ характерно наличие команд над вещественными числами и обработки кодов. Работа с идентификаторами реализуется аппаратными возможностями адресации памяти, обычно обеспечивающей доступ практически к любому хранимому в памяти данному или команде. Управление вычислениями может учитывать результаты промежуточных вычислений (ветвления и переключатели), выполнять итерирование участков повторяемости (циклы) и вызовы подпрограмм, а также обрабатывать внутренние и внешние прерывания. В качестве поддержки структур данных можно рассматривать пересылки блоков заданной длины, 60 а также средства работы с текстом программы. В качестве опорных языков рассмотрены ассемблеры MIX, MSX, P-код, RISC-машина, byte-код (muLisp и Java), MASM и БЭМШ. Традиционно ассемблер реализуют как упрощенный компилятор. Учитывая повышенную нагрузку низкоуровневого программирования на отладку программ, иногда включают в систему программирования дизассемблер и интерпретатор ассемблера, обеспечивающие кроме удобства отладки широкий спектр преобразования программ на ассемблере, их оптимизации и адаптации к развитию аппаратуры. Интерпретирующий автомат для ассемблера устроен проще, чем автомат для абстрактной машины SECD, благодаря встроенной реализации команд – языка конкретной машины и отсутствию локализации имен и их областей действия. Процесс перевода программы с языка ассемблера в язык машинных команд называют ассемблированием. Язык ассемблера оперирует такими данными, как адреса и значения. Нередко для наглядности в записи операндов команд вводится внешнее различие @адресов и #значений с помощью префиксных символов. Возможны специальные формы записи для блоков данных и литералов. При ассемблировании текст программы отображается в частично адресуемый код программы, исполнение которого обычно сводится к поячеечному изменению состояния памяти: ассемблер = (Текст → {Код | Адрес}): Пам [ячейка] → Пам Число слов, отводимое ассемблером под одну символическую команду, зависит не только от собственно кода команды, но и от метода адресации операндов, а возможно, и от других аспектов кодирования программ и данных, обсуждение которых здесь не предполагается. Достаточно констатировать, что программа при ассемблировании распадается на конечные последовательности команд K1 ... Kn, которым сопоставляются конечные интервалы машинных слов W1 ... Wm(a) в зависимости от а – системы аспектов кодирования: [K1 ... Kn ] → [W1 ... Wm(a)] Фактически, операндная часть команды – это адреса, специальные регистры, сумматоры, значения в общей памяти, шкала прерываний и состояний или что-то другое, специфичное для конкретной архитектуры. Парадигма низкоуровневого кодирования на ассемблере нацелена на учет любых особенностей компьютерных архитектур. Архитектура 61 компьютера часто определяется как множество ресурсов, доступных пользователю. Это система команд, общие регистры, слово состояния процессора и адресное пространство. Процесс ассемблирования заключается в следующем: – резервирование памяти для последовательности команд, образующих ассемблируемую программу; – сопоставление используемых в программе идентификаторов с адресами в памяти; – отображение ассемблерных команд и идентификаторов в их машинные эквиваленты. Для реализации такого процесса требуется счетчик адресов и таблица идентификаторов. Программист не знает абсолютных адресов ячеек памяти, занятых для хранения констант, команд и промежуточных результатов вычислений, но обычно предполагается, что последовательно написанные команды будут расположены в последовательных ячейках памяти. Язык ассемблера обычно различает следующие категории команд: – вычисления с результатом в сумматоре, для которых следующая команда расположена по соседству; – изменение части состояния общей памяти, при котором следующая команда расположена по соседству; – обработка текста программы без генерации нового кода; – управление со своими правилами выбора следующей команды. При записи команд на ассемблере принято структурировать строки на поля, предназначенные для последовательного размещения метки, кода команды, операндов и комментария. Наибольшее разнообразие возможных решений связано с формами адресации операндов на уровне машинного языка. В зависимости от команды используются разные методы адресации операндов. Обычно система команд ассемблера, кроме команд арифметических вычислений и передач управления, содержит команды манипулирования данными, их ввода-вывода через буфер обмена, возможно, доступный через механизм прерываний. При этом используется код состояния процесса, отражающий свойства текущей выполняемой команды, такие как выработка нулевого или ненулевого кода, отрицательного или положительного числа, переноса разряда за границы машинного слова и др. Имеются команды условного перехода, возвратный вызов процедуры с использованием регистра возврата и передача управления со счетчиком числа циклов. Встречаются и другие команды, разнообразие которых не 62 влияет на особенности ассемблирования и применения ассемблеров в системах программирования. Именно язык ассемблера традиционно выступает в системах программирования в роли конкретной машины (КМ) при компиляции программ. Программирование на ассемблере подразумевает знание специфики системы команд процессора, методов обслуживания устройств и обработки прерываний. Система команд может быть расширена микропрограммами и системными вызовами в зависимости от комплектации оборудования и операционной системы. Это влияет на решения по адресации памяти и коммутации комплекта доступных устройств. Но есть и достаточно общие соглашения о представлении и реализации средств обработки информации на уровне машинного кода. Обычно ассемблер обеспечивает средства управления распределением памяти и управления компиляцией кода независимо от системы команд, что позволяет программисту принимать достаточно точные решения на уровне машинного языка. Существуют средства отладочного исполнения и распечатки листингов. Управление ассемблированием обычно обеспечивает средства авторизации, взаимодействия с отладчиком, текстовым редактором, операционной системой и средствами приаппаратного уровня, доступными через операционную систему и аппаратные средства ввода- вывода (BIOS). По тексту программы при ассемблировании формируется код программы, выполняющий пошаговое преобразование памяти. Программирование на ассемблере требует знания особенностей применяемых команд, их операндов и результатов. Большинство команд изменяют один регистр, если не считать счѐтчик команд. Некоторые команды могут изменять более одного регистра. Например, умножение вещественных чисел может формировать регистр младших разрядов для вычислений с повышенной точностью, деление целых чисел может формировать регистр с остатком от деления, пересылка меняет содержимое целого ряда машинных слов. Спецификация команд абстрактной машины ассемблера может быть задана над тройкой Приведѐм пример системы команд. 63 Таблица 13 Пример системы команд ассемблера Обознач ение команды Описание команды 12 Примечание LDC Засылка адреса в сумматор. Подготовка операндов LDM Засылка адресуемого слова в сумматор. LDS Косвенная засылка слова в сумматор. RV Пересылка из сумматора в память. 13 Сохранение результата RVS Пересылка слова по адресу из сумматора в память. GO Безусловная передача управления. GS0 Условная передача управления по нулевому значению сумматора. Ветвление GS1 Условная передача управления по ненулевому значению сумматора. GSUB Передача управления с запоминанием адреса возврата в сумматоре. Подпрограмма DEC Вычитание 1 из содержимого сумматора. Арифметические операции INC Прибавить 1 к содержимому сумматора. ADD Прибавление адреса к содержимому сумматора. SUM Суммирование адресуемого слова и содержимого сумматора. Таблица 14 Пример спецификации команд ассемблера RA RA’ Примечание s (LDC Adr . c) m → (s:=Adr) c m Операнд из команды s (LDM Adr . c) m → (s:=[Adr]) c m Операнд из памяти (s:Adr) (LDS . c) m → (s:=[Adr]) c m Операнд по адресу в сумматоре s (RV Adr . c) m → s c (m|m.Adr:=[s]) Результат из сумматора (s:Adrs) (RVS Adr . c) m → s c (m|m.Adr:=[Adrs]) Результат по адресу s (GO Adr . c) m → s Adr m 12 Следующая команда расположена по соседству или задана командой передачи управления 13 Пересылки – это изменение части состояния общей памяти. 64 (s:0) (GS0 Adr . c) m → s Adr m (s:1) (GS1 Adr . c) m → s Adr m s (GSUB Adr . c) m → @c Adr m Укрупнение действий s (DEC . c) m → (s-1) c m s (INC . c) m → (s+1) c m s (ADD Adr . c) m → (s+Adr) c m s (SUM Adr . c) m → (s+[Adr]) c m Применение ассемблера для разработки многократно используемых модулей налагает определѐнные ограничения на структуру кода программы и его свойства: – перемещаемость. Свойство удобно, когда код программы устроен так, что его можно расположить по любому абсолютному адресу; – листание страниц памяти. Соотношение между адресуемой и реально доступной памятью может требовать пересмотра в процессе выполнения программы; – зависимость от данных. Программа должна учитывать готовность данных и вероятность их обновления, особенно в случае обмена информацией через порты или буферы устройств; – динамика размещения. Программа может размещаться в памяти пошаговым образом, методом раскрутки, с использованием динамической оптимизации, учитывающей статистику реального использования ее составляющих. Примеры программ решения типовых задач средствами ассемблера: Фрагмент программы Примечание LD HL, ADR 1 откуда LD DE, ADR 2 куда LD BC, 2048 сколько LDIR Установить регистр HL Установить регистр DE Установить регистр BC Переместить данные в соответствии с содержимым регистров HL, DE, BC Пример 1. Пример из ассемблера MSX: пересылка блока (ТД не имеет значения) Ассемблер отличается от компилятора меньшей сложностью исходного языка, перевод с которого в машинный язык можно выполнить «один-в- один». Ассемблер часто сопровождается возможностью дизассемблирования, что отличает его от большинства других языков программирования. Изучить язык ассемблера проще, чем любой язык 65 высокого уровня. Знание ассемблера помогает понимать код программы, подготовленной на других языках. Основной механизм укрупнения действий – передача управления подпрограмме. При необходимости уровень языка может быть повышен с помощью макросов. Императивный стиль программирования наследуется большинством ЯВУ, поддерживающих процедурно-императивное и объектно- ориентированное программирование. Таблица 15 Парадигматическая характеристика ассемблера Параметр Конкретика Эксплуатационная прагматика ЯП Ассемблер – средство эффективного программирования при решении задач доступа к полному спектру возможностей оборудования Регистры абстрактной машины S C M S – сумматор; C – поток команд программы с указателем на текущую команду; M – вектор памяти произвольного доступа. Результат рассредоточен по ячейкам памяти Категории команд абстрактной машины - вычисления с результатом в сумматоре, для которых следующая команда расположена по соседству; - изменение части состояния общей памяти, при котором следующая команда расположена по соседству; - обработка текста программы без генерации нового кода; - управление со своими правилами выбора следующей команды; - команды «знают», где их операнды. Реализационная прагматика - перемещаемость. Код можно расположить по любому абсолютному адресу; - листание страниц памяти; - зависимость от данных; - динамика размещения; - объектный код; - билистинг; 66 - прокрутка и отладчик; - реассемблирование. Парадигматическая специфика Классический язык императивного машинно-ориентированного программирования. 3.2. Стековая машина Forth Для машинно-ориентированных языков, таких как Forth [1], система вычислений распадается на подсистемы по величине обрабатываемого слова (16 и 32, возможно, 64). Основа работы с памятью – стек. Средства управления вычислениями обогащены средствами блокировки и кодирования программ, что позволяет повышать эффективность информационной обработки. Используется механизм замкнутых процедур с неявными – стековыми – параметрами. Стек реализован как указатель на текущий элемент в предположении, что перед ним по порядку расположены предшествующие элементы. Программа – отдельный поток, использующий расширяемый словарь. Принята постфиксная запись, удобная для стековой обработки данных. Стек-ориентированная дисциплина обработки освобождает от необходимости в понятии «переменная», хотя оно при необходимости моделируется. Программирование на Forth-е сопровождается систематической сверткой понятий, синтаксис применения которых созвучен польской записи. Можно сказать, что хорошая программа на Forth-е – это специализированная виртуальная машина, приспособленная к дальнейшему расширению по мере развития постановки задачи. Интерпретатор языка Forth сортирует слова по принадлежности словарю: – слова, не найденные в словаре, записываются в стек для предстоящей обработки; – словарным словам, встроенным в интерпретатор, соответствует правило преобразования стека; – возможно определение новых слов, запоминаемое в словаре (от «:» до «;»); – за корректность воздействий на стек отвечает программа; – результатом считается состояние стека при завершении программы. |