Спецификации в виде графических схем.

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

спецификации в виде графических схем. - student2.ru

Рис. 3.1. Граф-диаграмма системы сопровождения данных.

Граф-диаграммы. Иногда называемые графами потоков данных. Каждый кружок на такой диаграмме отображает некоторое преобразование данных. Потоки данных отмечаются стрелками. Этот тип схем можно использовать как на системном уровне для описания внешних входов и выходов программ, так и при проектировании самих программ для описания перемещений данных между отдельными модулями. На рисунке 3.1 представлен пример граф-диаграммы системы сопровождения данных.

Функциональные схемы. Функциональная схема системы состоит из одного или нескольких прямоугольных блоков, содержащих названия программ. Эти блоки соединяются входящими в них стрелками с источниками и исходящими из них стрелками - с приемниками данных. Источники и приемники изображаются в виде блоков, очертания которых напоминают определенные физические носители информации (некоторые блоки представлены на рис. 3.2). В каждом блоке записано имя программы или набора данных, иногда оно дополняется информацией, раскрывающей назначение блока. Основное внимание в схемах этого типа уделяется описанию потоков данных в системе и используемых наборов данных. На рисунке 3.3. изображена функциональная схема фрагмента системы корректировки главного файлов.

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

спецификации в виде графических схем. - student2.ru

Рис. 3.3. Функциональная схема корректировки главного файла

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

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

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

Блок решения. Этот символ используется для обозначения переходов управления по условию. Для каждого блока решения должны быть указаны: вопрос, решение, условия или сравнение, которые он определяет. Стрелки, выходящие из этого блока, должны быть помечены соответствующими ответами так, чтобы были учтены все возможные ответы.

Блок обработки. Этот символ применяется для обозначения одного или нескольких операторов, изменяющих значение, форму представления или размещения информации. Для улучшения наглядности схемы несколько отдельных блоков обработки могут быть объединены в один блок.

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

Блок ввода/вывода. Этот символ используется для обозначения операций ввода/вывода информации. Отдельным логическим устройствам или отдельным функциям обмена должны соответствовать отдельные блоки. В каждом блоке указывается тип устройства или файла, тип информации, участвующий в обмене, а также вид операции обмена.

спецификации в виде графических схем. - student2.ru

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

Блок комментария. Этот символ позволяет включать в структурные схемы пояснения к функциональным блокам. Частое использование комментариев нежелательно: оно усложняет структурную схему.

Структурные схемы можно применять на любом уровне абстракции. Основная тенденция в использовании структурных схем в настоящее время - не указание последовательности операций, а группирование символов, выражающих базовые конструкции: следование, выбор, повторение. На рис. 3.9 показаны схемы этих управляющих конструкций.

спецификации в виде графических схем. - student2.ru

спецификации в виде графических схем. - student2.ru

Схемы Насси-Шнейдермана. Способ изображения модуля с помощью схем Насси-Шнейдермана представляет собой попытку использования требований структурного программирования (см. ниже) в структурных схемах модулей. Он позволяет изображать схему передач управления не с помощью явного указания линий переходов по управлению, а с помощью представления вложенности структур. Некоторые из используемых в этом способе символов соответствуют символам структурных схем. Эти символы показаны на рисунке 3.10. Каждый блок имеет форму прямоугольника и может быть вписан в любой внутренний прямоугольник любого другого блока. Блоки помечаются тем же способом, что и блоки структурных схем, т.е. с использованием предложений на естественном языке или с помощью математических нотаций. Если использовать символы схем Насси-Шнейдермана одновременно с дополнительными символами структурных схем для изображения множественных выходов и обработки прерываний, то представление рассматриваемого модуля может быть упрощенно.

Тема: Методы структурного программирования.

Основные вопросы, рассматриваемые на лекции:

1. Понятие структурного программирования и его требования.

2. Основные конструкции структурных программ.

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

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

· Употребление операторов перехода типа GOTO следует избегать всюду, где это возможно. Наихудшим применением GOTO считается переход на оператор, расположенный выше (раньше) в тексте программы.

· По возможности следует отказаться от использования оператора ELSE Конструкция ELSE нужна только в той редкой ситуации, когда конструкция THEN изменяет одну из переменных в условии.

· Программа должна быть написана в приемлемом стиле, облегчающем её понимание и модификацию.

· Каждый модуль должен иметь ровно один вход и один выход.

· Программа представляет собой простое и ясное решение задачи.

Структурные программы составляются из трех основных строительных конструкций (рис.1 ) управления вычислительным процессом:

· следование — обозначает последовательное выполнение действий;

· ветвление — соответствует выбору одного из двух вариантов действий в зависимости от условия (значения предиката);

· цикл с предусловием — определяет повторение действий до тех пор, пока не будет нарушено заданное условие, выполнение которого проверяется перед началом каждого повторения.

Помимо базовых могут использоваться еще три управляющие конструкции, которые легко реализуются на их основе:

· выбор — обозначает выбор одного варианта действий из нескольких в зависимости от значения некоторой величины или условия;

· цикл с постусловием — определяет повторение действий до тех пор, пока не будет выполнено некоторое условие, проверка которого осуществляется после каждого повторения;

· цикл с заданным числом повторений (счетный цикл) — определяет повторение действий указанное число раз.

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

спецификации в виде графических схем. - student2.ru

Рис. 1. Основные конструкции «структурного программирования».

Основные конструкции структурного программирования, представленные на псевдокоде

Конструкция Псевдокод Конструкция Псевдокод
Следование <действие 1> <действие 2> Цикл с предусловием ЦИКЛ-ПОКА <условие> <действие> ВСЁ-ЦИКЛ
Ветвление ЕСЛИ <условие> ТО <действие 1> ИНАЧЕ <действие 2> ВСЁ-ЕСЛИ Цикл с постусловием ВЫПОЛНЯТЬ <действие> ДО <условие>
Выбор ВЫБОР <условие> <код 1>: <действие 1> <код 2>: <действие 2> … ИНАЧЕ: <действие N> ВСЁ-ВЫБОР Счетный цикл ДЛЯ <индекс> = <k1>, <k2>, <d> <действие> ВСЁ-ЦИКЛ

Метод пошаговой детализации. Для получения текстов программ и составляющих их модулей, соответствующих принципам структурного программирования, рекомендуется использовать пошаговую детализацию. Сущность данного метода заключается в следующем: первоначально управляющая логика программы или модуля описывается в терминах гипотетического языка «очень высокого уровня», а затем каждое предложение постепенно детализируется в терминах языка более низкого уровня до тех пор, пока, наконец, не будет достигнут уровень используемого языка программирования. На протяжении всего процесса логика выражается основными конструкциями структурного программирования. Таким образом, метод пошаговой детализации предполагает разбиение процесса разработки программного текста на ряд шагов. На первом шаге описывается общая схема работы модуля в наглядной текстовой форме с использованием базовых («очень крупных») понятий, ориентированная на восприятие и понимание её человеком. На каждом следующем шаге выполняется уточнение и детализация одного из понятий, полученного на каком-либо предыдущем шаге. Уточняемое понятие выражается либо через новые, более «мелкие» понятия, либо в терминах (конструкциях) языка программирования, выбранного для разработки модуля. В любом случае, операции управления вычислительным процессом следует представлять с помощью конструкций структурного программирования, а полученное описание должно быть наглядным и достаточно простым для понимания. Этот процесс завершается, когда все уточняемые понятия будут выражены на используемом языке программирования. Последний шаг состоит в формировании готового текста модуля путем замены всех уточняемых понятий соответствующими программными фрагментами и выражения всех вхождений конструкций структурного программирования через средства языка.

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

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

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

Лекция № 7.

Тема: Структурные преобразования блок-схем.

Основные вопросы, рассматриваемые на лекции:

1. Простые преобразования.

2. Метод введение дублирующих элементов.

3. Метод введение переменной состояния.

Простые преобразования. Связаны с представлением основных конструкций структурного программирования посредством единственного блока «Процесс». При необходимости упрощения схемы конструкция «сворачивается» в этот блок, а в случае детализованного описания — «разворачивается» из блока.

спецификации в виде графических схем. - student2.ru

Рис. 1. Структурные преобразования: «дублирование блоков».

Метод введение дублирующих элементов. Данное преобразование позволяет исключить из блок-схемы варианты передачи управления, не согласующиеся с концепциями структурного программирования, путем введения в неё по определенным правилам дополнительных элементов, эквивалентных уже существующим. Пусть, например, имеется схема, представленная на рис.1.а. Стремление использовать блоки 7, 9, 10, 11 в ветвях, начинающихся в блоках 4 и 5, привело к запутанным связям по управлению. Дублируя блоки 7, 9, 10, 11 можно привести исходную схему к структурированному виду (рис.1.б). При дублировании, строя очередной фрагмент после разветвления, каждый раз вводят необходимые блоки, не обращая внимания на то, что они уже введены на альтернативных участках схемы.

Метод введение переменной состояния. Данный подход также позволяет устранить из схемы неструктурные способы передачи управления. Процесс преобразования включает в себя следующие операции:

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

Вводится новая переменная, принимающая значение в диапазоне от 0 до n, называемая переменной состояния.

Вводятся n операций присвоения значений переменной состояния. С каждым блоком связывается одна или несколько (для блока «Решение» или «Выбор» в соответствии с количеством его выходов) операций, в которых значения переменной становится равным номеру очередного исполняемого блока.

Вводятся n операций анализа переменной состояния в соответствии со следующим принципом: если значение переменной состояния равно m (0<m<=n), то управление передается блоку с номером m. Операция проверки значения переменной на равенство нулю резервируется для случая выхода из схемы.

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

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

спецификации в виде графических схем. - student2.ru

спецификации в виде графических схем. - student2.ru

Рис. 2. Структурные преобразования. Введение переменной состояния.

Основы языка программирования Ассемблер.

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

Реализация большинства операций в языке Ассемблер основана на непосредственном использовании регистров процессора. Микропроцессорная память процессора Intel 8088 включает 14 двухбайтовых запоминающих регистров. По назначению они делятся на 4 группы.

· Универсальные регистры AX, BX, CX, DX. Каждый из универсальных регистров может использоваться для временного хранения любых данных. Разрешается работать как с регистром целиком, так и отдельно с каждой его половиной. Для обращения к старшим байтам используются регистры AH, BH, CH, DH, для обращения к младшим байтам — регистры AL, BL, CL, DL.

· Сегментные регистры CS, DS, SS, ES используются для хранения начальных адресов полей памяти (сегментов), отведенных в программах для команд (CS), данных (DS), стека (SS), данных при межсегментных пересылках (ES).

· Регистры смещений IP, SP, BP, SI, DI служат для хранения относительных адресов ячеек памяти внутри сегментов, т.е. смещений относительно начала сегментов.

· Регистр флагов FL содержит 9 одноразрядных флагов, управляющих прохождением программы в компьютере. Например, ZF — флаг нуля, устанавливаемый в 1, если результат операции равен нулю; SF — флаг знака, устанавливаемый в 1, если после арифметической операции получен отрицательный результат; OF — флаг переполнения, устанавливаемый в 1 при арифметическом переполнении; IF — флаг прерываний, разрешающий (значение 1) или запрещающий (значение 0) прерывания.

Ассемблерная программа может включать в себя следующие основные элементы: константы, команды, директивы и модификаторы. Константы языка ассемблер подразделяются на два типа: целые числа и строки. Целые числа могут быть представлены в двоичном, десятичном и шестнадцатеричном виде. Строки заключаются в одинарные или двойные кавычки.

Команды или операторы имеют следующий формат:

[<Метка>[:]] <Код оператора> [<Операнды>] [;<Комментарий>]

Основные типы команд.

· Выполнения арифметических операций. Например, команда ADD <приемник>, <источник> осуществляет сложение двоичных чисел, а именно содержимое источника складывается с содержимым приемника, при этом операнды должны иметь одинаковый формат. Команда MUL <источник> предназначена для перемножения чисел без учета знака. В этом случае операнд представляет собой 8- или 16-битовый множитель, множимое хранится соответственно в регистре AL или AX, а произведение будет сохранено в регистре AX или AX и DX. Команда CMP <приемник>, <источник> выполняет сравнение двоичных чисел.

· Выполнения логических операций. Например, команды OR <приемник>, <источник> и AND <приемник>, <источник> — выполняют соответственно поразрядную дизъюнкцию и конъюнкцию битов операндов.

· Пересылки данных. Например, MOV <приемник>, <источник> — пересылает в зависимости от формата операндов один байт или одно слово между регистрами или между регистром и памятью, т.е. заносит непосредственное значение в регистр или память.

· Передачи управления. Команда безусловного перехода: JMP <операнд> — выполняет передачу управления по заданному адресу. В качестве операнда указывается прямой или косвенный адрес. Команды условной передачи управления, называемые также иногда триггерами, имеют вид: J<условие> <метка>. Например, JG — переход, если больше, т.е., если флаги ZF=0 и SF=OF; JL — переход, если меньше, т.е., если флаг SF¹OF; JE/JZ — переход, если равно/нуль, т.е., если флаг ZF=1; JS — переход, если знак отрицательный, т.е., если флаг SF=1. К этой группе относятся также следующие команды: LOOP — управления циклом, CALL — вызова процедуры, RET — возврата из процедуры.

· Прерывания работы программы. Прерывание — это приостановка выполнения программы процессором с целью выполнения другой программы (программы обработки прерывания), после завершения которой, как правило, продолжается выполнение прерванной программы с момента её прерывания. Основной представителем этой группы является команда INT <номер прерывания>, прерывающая выполнение программы и передающая управление подпрограмме обработки, заданной номером прерывания.

· Управления процессором. Например, ST* и CL* — установки и сброса флагов, HLT — останова, WAIT — ожидания, NOP — холостого хода.

· Обработки строк символов. Например, MOVS — пересылки, CMPS — сравнения, LODS — загрузки, SCAS — сканирования.

Директивы или псевдооператоры ассемблера представляют собой инструкции транслятору. В отличие от команд, являющихся инструкциями машине, директивы обрабатываются только в ходе трансляции программы в машинный код, а не в ходе её выполнения на компьютере. Директивы имеют следующий формат:

[<Идентификатор>] <Код псевдооператора> [<Операнды>] [;<Комментарий>]

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

[<имя>] D<формат> <выражение>[, <выражение>][,…]

где имя — набор символов, начинающийся с буквы, используемый для ссылки на переменную или поле данных. Формат может иметь следующие значения: B — байт, W — слово (2 байта), D — двойное слово (4 байта), Q — 8 байтов, T — 10 байтов. Выражение показывает, какое количество элементов памяти необходимо выделить и какие данные там будут содержаться.

Также в программе используются директивы определения сегментов:

<имя сегмента> segment

<содержимое сегмента>

<имя сегмента> ends

В программе можно использовать 4 сегмента (по числу сегментных регистров) и для каждого из них в сегменте кода следует указывать соответствующий регистр сегмента директивой ASSUME. Например:

COMMANDS segment

assume CS:COMMANDS, DS:DATA, SS:STACK

COMMANDS ends

После директивы ASSUME необходимо загрузить адрес начала сегмента данных в регистр DS. Инициализация сегментных регистров CS и SS выполняется автоматически.

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

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

TITLE sum1n.asm - программа вычисляет сумму целых чисел от 1 Þ до N (N < 1000)

STACK segment ; Начало сегмента стека

dw 64 dup(?)

STACK ends ; Конец сегмента стека

DATA segment ; Начало сегмента данных

ZeroCode = 48 ; ASCII-код цифры 0

; Задаем строки с сообщениями, используемые в ходе работы Þ программы

; Символ "$" в конце строк - требование DOS

TitleMsg db "Программа вычисляет сумму целых чисел от 1 до N Þ (N < 1000)", 13, 10, "$"

InputMsg db "Введите число N: ", "$"

ResultMsg db 13, 10, "Сумма равна ", "$"

; Объявляем необходимые переменные

M10 dw 10 ; Множитель 10

N dw ? ; Введенное число N в двоичном формате

P10 dw 1 ; Степень 10

StrN db 4, 5 dup(0) ; Число N в формате строки Þ
(первый байт - максимальное число вводимых символов)

StrSum db 6 dup(0), "$" ; Сумма в формате строки

Sum dd 0 ; Вычисляемая сумма

DATA ends ; Конец сегмента данных

CODE segment ; Начало сегмента кода

assume CS:CODE, DS:DATA, SS:STACK ; Связываем сегментные Þ регистры с сегментами

main proc far ; Объявляем главную программную процедуру Þ (требование DOS)

; Записываем адрес префикса программного сегмента в стек Þ (требование DOS)

push ds

sub ax, ax

push ax

mov ax, DATA ; Пересылаем адрес сегмента данных в регистр AX

mov ds, ax ; Устанавливаем регистр DS на сегмент данных

; Выводим сообщение о назначении программы

mov AH, 09h ; Определяем в качестве обработчика прерывания Þ DOS-функцию вывода строки на экран

mov DX, offset TitleMsg ; Задаем смещение к началу строки

int 21h ; Выводим строку

; Выводим сообщение с запросом на ввод числа N

mov AH, 09h

mov DX, offset InputMsg

int 21h

; Запрашиваем число и сохраняем его в переменной StrN

mov AH, 0Ah ; Определяем в качестве обработчика прерывания Þ DOS-функцию ввода строки символов

mov DX, offset StrN ; Задаем смещение к началу строки

int 21h ; Запрашиваем строку

; Теперь в переменной StrN хранятся следующие значения Þ (байты перечисляются слева направо):

; 1-й байт - максимальное число вводимых символов Þ (для данного примера - 4)

; 2-й байт - действительное число введенных символов

; последующие байты - ASCII-коды введенных символов, Þ последний из которых всегда - 13 (код клавиши Enter)

; Переводим введенное число в двоичный формат

; (в данный момент число представлено двоичными кодами цифр, Þ т.е. ASCII-кодами введенных символов)

mov P10, 1 ; Заносим 1 в степень 10

mov DI, 0 ; Обнуляем регистр, в котором будем сохранять Þ результат

mov SI, offset StrN + 1 ; Заносим в регистр SI адрес Þ ячейки, в которой хранится количество цифр числа Þ
(хранится во втором байте переменной StrN)

mov BL, [SI] ; Заносим в младший байт регистра BX Þ количество цифр числа

mov BH, 0 ; Обнуляем старший байт регистра BX

mov SI, offset StrN + 2 ; Заносим в регистр SI адрес Þ ячейки первой цифры введенного числа

LS2B: mov AL, [SI + BX - 1] ; Заносим в младший байт Þ регистра AX ASCII-код текущей цифры числа (цифры перебираем справа налево)

sub AL, ZeroCode ; Вычитаем из кода цифры код цифры 0 для Þ получения соответствующего числа

mov AH, 0 ; Обнуляем старший байт регистра AX

mul P10 ; Умножаем значение регистра AX на число 10 в Þ степени, соответствующей позиции текущей цифры

add DI, AX ; Добавляем полученное произведение к конечному Þ результату

mov AX, P10 ; Сохраняем степень 10 в регистре AX

mul M10 ; Увеличиваем степень 10 на порядок (содержимое Þ регистра AX умножаем на 10)

mov P10, AX ; Сохраняем новое значение степени в Þ соответствующей переменной

dec BX ; Определяем номер следующей цифры

jnz LS2B ; Переходим к обработке следующей цифры, если Þ перебраны еще не все цифры числа

; Теперь в регистре DI находится введенное число в двоичном Þ формате

; Запоминаем его в переменной N

mov N, DI

; Вычисляем сумму от 1 до N

mov AX, 0 ; Обнуляем регистр AX

LSM: inc AX ; Увеличиваем содержимое регистра AX на 1, Þ определяя очередное слагаемое

add word ptr Sum[2], AX ; Добавляем содержимое регистра AX Þ к младшему слову суммы

adc word ptr Sum[0], 0 ; Добавляем 0 к старшему слову Þ суммы с учетом переноса от предыдущего сложения Þ
(учитываем перенос, если он был)

cmp AX, N ; Если содержимое регистра AX меньше числа N,

JB LSM ; переходим к следующему слагаемому

; Переводим полученную сумму в форму строки

mov SI, offset StrSum + length StrSum - 1 ; Заносим в Þ регистр SI адрес ячейки для хранения последней цифры числа

mov DX, word ptr Sum[0] ; Заносим в регистры DX:AX число, Þ которое будем переводить в строку

mov AX, word ptr Sum[2]

LB2S: div M10 ; Делим число, находящееся в регистрах DX:AX Þ на 10

add DL, ZeroCode ; Добавляем к остатку от деления код Þ цифры 0 для получения ASCII-кода цифры

mov [SI], DL ; Сохраняем найденную цифру в соответствующей Þ позиции строки с результирующим числом

dec SI ; "Переходим" к предыдущей цифре числа

mov DX, 0 ; Обнуляем регистр DX

cmp AX, 0 ; Если частное отлично от нуля (определены не Þ все цифры числа),

jne LB2S ; то переходим к вычислению очередной цифры числа

; Выводим сообщение, предшествующее выводу результата

mov AH, 09h

mov DX, offset ResultMsg

int 21h

; Выводим полученное число

mov AH, 09h

mov DX, offset StrSum

int 21h

ret ; Выходим из основной процедуры

main endp ; Конец основной процедуры

CODE ends ; Конец сегмента кода

END MAIN ; Конец программы (требование DOS)

Лекция № 13.

Тема: Программирование обработки баз данных. Основы языка SQL.

Основные вопросы, рассматриваемые на лекции:

2. Введение в языки программирования баз данных.

3. Основы синтаксиса языка SQL. Синтаксис оператора SELECT.

4. Объединение данных из нескольких таблиц. Ключевое слово JOIN.

5. Предложение WHERE. Предикаты для отбора записей.

6. Агрегирующие функции и группировка данных. Отбор групп.

7. Подзапросы и предикаты для работы с ними.

8. Объединение результатов запросов с помощью конструкции UNION.

9. Изменение содержимого таблицы. Операторы INSERT, UPDATE, DELETE.

Язык программирования баз данных (ЯПБД) обычно включает в себя два подъязыка: язык определения данных, используемый для определения схемы (структуры) базы данных (БД), и язык манипулирования данными, предназначенный для работы с данными, хранимыми в базе. Как правило, в этих языках отсутствуют конструкции управления вычислительным процессом, такие как условные операторы или операторы цикла. Для устранения этого ограничения многие системы управления базами данных (СУБД) предоставляют возможность внедрения операторов ЯПБД в тот или иной язык программирования высокого уровня, например C++, Pascal, Java, FoxPro, называемый базовым языком. Перед компиляцией программы на базовом языке, включающей операторы ЯПБД, они транслируются в конструкции базового языка, обеспечивающие вызов соответствующих подпрограмм СУБД. Кроме того, большинство СУБД и сред разработки приложений для работы с БД предоставляют инструментальные средства для интерактивного выполнения операторов ЯПБД.

SQL представляет собой стандартизированный и наиболее распространенный на данный момент ЯПБД для реляционных СУБД. Он включает в себя как язык определения данных, так и язык манипулирования данными. Оператор языка состоит из зарезервированных (ключевых) слов, слов, определяемых пользователем, литералов и знаков операций, скомпонованных в соответствии с установленными синтаксическими правилами. Зарезервированные слова являются частью языка SQL и позволяют описать выполняемую операцию. Слова, определяемые пользователем, представляют собой имена различных объектов БД, над которыми надо выполнить операцию. Литералы задают используемые в операторе константы. Все нечисловые константы должны заключаться в одинарные кавычки. Однако, в некоторых диалектах языка для представления литералов того или иного типа, например дат и времени, могут применяться другие символы. Во многих реализациях SQL каждый оператор должен заканчиваться специальным символом, как правило точкой с запятой.

Язык манипулирования данными SQL включает следующие основные операторы:

· SELECT — для извлечения данных из базы;

· INSERT — для добавления данных в таблицу;

· UPDATE — для изменения данных в таблице;

· DELETE — для удаления данных из таблицы.

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

SELECT [ALL | DISTINCT] [{<таблица>|<псевдоним>}.]{* | <выражение>
[AS <другое имя столбца>]} [,…]

FROM <таблица> [<псевдоним>] [,…]

[WHERE <условие отбора записей>]

[GROUP BY <группируемый столбец>, [,…]]

[HAVING <условие отбора групп>]

[ORDER BY <сортируемый столбец> [ASC | DESC] [,…]]

Обязательными в операторе являются только конструкции SELECT и FROM. Ключевое слово ALL указывает на необходимость включения в результирующую выборку всех записей, удовлетворяющих запросу, в том числе повторяющихся, если они есть. Ключевое слово DISTINCT используется для удаления дублирующих строк, то есть в результирующую выборку не будут включаться записи, совпадающие по значениям всех полей с одной из ранее отобранных. Параметр <таблица> представляет собой имя таблицы БД, из которой осуществляется выборка. <выражение> задает имя столбца таблицы или выражение из нескольких имен, определяющее вычисляемое поле, содержимое которого включается в результирующую выборку. Выражение помимо имен столбцов, арифметических операций сложения, вычитания, умножения и деления, а также круглых скобок, используемых в сложных выражениях, может содержать в зависимости от диалекта языка те или иные функции от значений полей. Звездочка (*) вместо имени столбца указывает на необходимость включения всех полей. Название любого столбца в результирующей таблице может быть изменено с помощью параметра <другое имя столбца>, что обычно используется для именования вычисляемых полей. Если данные извлекаются из нескольких таблиц, которые имеют совпадающие по названию столбцы, то имя каждого поля должно предваряться именем или псевдонимом таблицы. Псевдоним задает сокращенное имя для таблицы, используемое в пределах данного оператора. Параметр <условие отбора записей> описывает фильтр, определяющий какие строки должны быть включены в результат. <группируемый столбец> задает имя поля, по значениям которого производится группировка записей. Параметр <условие отбора групп> представляет фильтр, накладываемый на сформированные группы. Наконец, <сортируемый столбец> указывает название поля, в соответствии со значениями которого должна быть упорядочена формируемая выборка. Результат выполнения оператора представляет собой таблицу, в которой находятся извлеченные из БД сведения.

Далее на примерах приведены различные варианты и особенности применения оператора SELECT.

Пример 1. Вывести список товаров с указанием помимо существующих данных общей стоимости товара, имеющегося на складе. Список отсортировать по убыванию цены, а при равной цене — по названию.

SELECT *, price*quantity AS cost

FROM Product

ORDER BY price DESC, name ASC;

Результирующая таблица включает в себя все поля из таблицы Product и дополнительное вычисляемое поле, значения которого представляют собой стоимость всех единиц товара, имеющихся на складе. Для этого поля задано имя, которое может быть использовано для обращения к нему в других частях оператора. Конструкция ORDER BY выполняет упоряд

Наши рекомендации