ВСР МДК Системное программирование

Куликов Виталий Сергеевич

Внеаудиторная самостоятельная работа

Скачать:

ВложениеРазмер
Microsoft Office document icon mdk_p_mu_srs.doc340.5 КБ

Предварительный просмотр:

Областное государственное бюджетное профессиональное образовательное учреждение

«Смоленский политехнический техникум»

МЕТОДИЧЕСКИЕ УКАЗАНИЯ

ДЛЯ ОБУЧАЮЩИХСЯ ПО ВЫПОЛНЕНИЮ

ВНЕАУДИТОРНОЙ САМОСТОЯТЕЛЬНОЙ РАБОТЫ

Для специальности 09.02.03 «Программирование в компьютерных системах»

«ПМ01. Разработка программных модулей программного обеспечения

для компьютерных систем

МДК01.01 Системное программирование»

Смоленск

2015

Рассмотрено и одобрено

цикловой методической комиссией

радиотехнических дисциплин

Председатель ЦМК _________ В.С. Куликов

Протокол № __

«__»____________________20__г.

Составитель: Куликов В.С., преподаватель Смоленского политехнического техникума


Тема: 1.1 Современные системы программирования.

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

Количество задач

Характер задачи (обязательный, рекомендательный)

Норма времени

(в часах по рабочей программе)

Срок выполнения (в неделях)

Форма представления материала

(по каждой задаче)

Форма контроля каждой задачи

№1

№2

№3

Обязательное

Обязательное

Рекомендательное

6

1 неделя

2 недели

3 недели

Доклад

Презентация

Видео

Выступление

Защита

Анализ

Задание

№1 Выполнить доклад по истории одного из языков программирования по выбору студента, доклад может выполняться группой студентов, не более 4 человек.

№2 Сделать презентацию по выбранным для доклада языкам программирования, работа выполняется теми же группами или индивидуально.

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

Рекомендации

по выполнению ВСР:

Обзор и общая характеристика языков программирования

по оформлению результатов:

Приложения XXI века. В свое время язык Ada был разработан с целью устранения  дублирования  возможностей  в  конкурирующих  между  собой языках  программирования.  В  настоящее  время  ситуация  гораздо  более сложная, чем в 60-е гг. ХХ в. Сейчас мы имеем больше областей применения, для которых разработаны и реализованы специализированные языки программирования, хорошо адаптированные к решению возникающих задач.  Более  того,  в  каждой  области  применения  существует  несколько подобных языков. Приложения  для  обработки  деловой  информации. По-прежнему  основным языком в этой области остается COBOL, хотя иногда используются

языки С  и  C++. Однако  сценарий  оценки  возможных  вариантов  кардинально изменился. Электронные таблицы, используемые на персональных компьютерах,  полностью  реформировали  эту  область  применения. В  то время  как  раньше  программист  тратил  несколько  месяцев  на  создание обычной  программы  делового  планирования,  теперь  аналитик  может  за несколько часов составить много таких таблиц. Языки четвертого поколения 4GL (Fourth Generation Languages) также  заняли определенную  нишу  в  этой  области.  Языки  4GL – это  языки, специально  адаптированные  под  конкретные  области  применения  обработки деловой информации. Как правило, они имеют средства для создания оконного интерфейса и простой доступ к записям базы данных. Также предусмотрены специальные возможности для создания форм заполнения стандартного  бланка  и  генерирования  красиво  оформленных  отчетов. Иногда компиляторы языков 4GL в качестве результата выдают программы на языке COBOL. Средства, позволяющие вести диалог пользователя (то есть покупателя) и

компании  (продавца)  посредством «всемирной  паутины», дали толчок к развитию  новой  роли  языков  программирования.  Язык Java  был  разработан  для обеспечения конфиденциальности частной жизни пользователя, а такие языки, как Perl и JavaScript, позволяют продавцу получить  от  пользователя  сведения, необходимые для проведения сделки.

по выбору средств:

MASM, TASM, Borland C++Builder

Литература:

  1. Алгоритмизация и программирование: учебное пособие (ГРИФ) // Канцедал С.А.  – М.: ИТ Форум: ИНФРА – М, 2010. – 252с.
  2. Операционные системы, среды и оболочки. Учеб. пособие// Партыка Т. Л., Попов И. И. -2-е изд., испр. и доп., - М.: Форум, 2010. - 528с.
  3. Программирование на языках высокого уровня: учебное пособие // Голицына О.Л., Попов И.И. – М.: Форум, 2010. – 496с.

Тема: 1.2 Машинно-ориентированная система программирования Ассемблер. Использование транслятора Turbo Assembler при разработке программ.

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

Количество задач

Характер задачи (обязательный, рекомендательный)

Норма времени

(в часах по рабочей программе)

Срок выполнения (в неделях)

Форма представления материала

(по каждой задаче)

Форма контроля каждой задачи

№1

№2

№3

Обязательное

Обязательное

Рекомендательное

30

2 недели

2 недели

3 недели

Листинг*.hex

Э3, *.dsn

Инструкция

Компиляция

Моделирование

Защита

Задание

№1 Разработка программы на языке Assembler по индивидуальному заданию на основании типовых производственных задач (с комментариями в листинге построчно).

№2 Моделирование аппаратной части для выполнения разработанной программы.

№3 Разработка инструкции по использованию программных и аппаратных средств реализации типовых производственной задачи.

Рекомендации

по выполнению ВСР:

Алгоритмы работы Ассемблеров

Двухпроходный Ассемблер — первый проход

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

Алгоритм работы 1-го прохода двухпроходного Ассемблера показан на рисунке.

F        Блок1: Начало 1-го прохода ассемблирования.

F        Блок2: Начальные установки:

u        установка в 0 счетчика адреса PC;

u        создание пустой таблицы символов;

u        создание пустой таблицы литералов;

u        открытие файла исходного модуля;

u        установка в FASLE признака окончания.

F        Блок3: Признак окончания TRUE?

F        Блок4: Считывание следующей строки исходного модуля. Добавка к счетчику адреса устанавливается равной 0.

F        Блок5: При считывании был обнаружен конец файла?

F        Блок6: Если конец файла обнаружен до того, как обработана директива END, — ошибка (преждевременный конец файла), при этом также устанавливается признак окончания обработки.

F        Блок7: Лексический разбор оператора программы. При этом:

u        выделяется метка/имя, если она есть;

u        выделяется мнемоника операции;

u        выделяется поле операндов;

u        удаляются комментарии в операторе;

u        распознается строка, содержащая только комментарий.

F        Блок8: Строка содержит только комментарий? В этом случае обработка оператора не производится.

F        Блок9: Мнемоника операции ищется в таблице директив.

F        Блок10: Завершился ли поиск в таблице директив успешно?

F        Блок11: Если мнемоника была найдена в таблице директив, происходит ветвление, в зависимости от того, какая директива была опознана.

F        Блок12: Обработка директив типа DD (определения данных) включает в себя:

u        выделение элементов списка операндов (одной директивой DD может определяться несколько объектов данных);

u        определение типа и, следовательно, размера объекта данных, заданного операндом;

u        обработка для каждого операнда возможного коэффициента повторения.

F        Блок13: Добавка к счетчику адреса устанавливается равной суммарному размеру объектов данных, определяемых директивой.

F        Блок14: Обработка директив типа BSS подобна обработке директив типа DD.

F        Блок15: Добавка к счетчику адреса устанавливается равной суммарному объему памяти, резервируемому директивой.

F        Блок16: Обработка директивы END состоит в установке в TRUE признака окончания обработки.

F        Блок17: Обработка директивы включает в себя вычисление значения имени и занесение его в таблицу символов.

F        Блок18: Обработка прочих директив ведется по индивидуальным для каждой директивы алгоритмам. Существенно, что никакие директивы, кроме DD и BSS, не изменяют нулевого значения добавки к счетчику адреса.

F        Блок19: Если мнемоника операции не найдена в таблице директив, она ищется в таблице команд.

F        Блок20: Завершился ли поиск в таблице команд успешно?

F        Блок21: Если мнемоника не была найдена в таблице команд, — ошибка (неправильная мнемоника).

F        Блок22: Если мнемоника найдена в таблице команд — определение длины команды, она же будет добавкой к счетчику адреса.

F        Блок23: Есть ли в операторе литерал?

F        Блок24: Занесение литерала в таблицу литералов (если его еще нет в таблице).

F        Блок25: Была ли в операторе метка?

F        Блок26: Поиск имени в таблице символов.

F        Блок27: Имя в таблице символов найдено?

F        Блок28: Если имя найдено в таблице символов — ошибка (повторяющееся имя).Если имя не найдено в таблице символов — занесение имени в таблицу символов.

F        Блок29: Формирование и печать строки листинга.

F        Блок30: Модификация счетчика адреса вычисленной добавкой к счетчику

F        Блок31: Печать строки листинга и переход к чтению следующего оператора.

F        Блок32: При окончании обработки — закрытие файла исходного модуля.

F        Блок33: Были ли ошибки на 1-м проходе ассемблирования?

F        Блок34: Формирование литерального пула.

F        Блок35: Выполнение 2-го прохода ассемблирования.

F        Блок36: Конец работы Ассемблера.

Определение длины команды

Эта задача может решаться существенно разным образом для разных языков. В языках некоторых Ассемблеров мнемоника команды однозначно определяет ее формат и длину (S/390, все RISC-процессоры). В этом случае длина команды просто выбирается из таблицы команд. В других языках длина и формат зависит от того, с какими операндами употреблена команда (Intel). В этом случае длина вычисляется по некоторому специфическому алгоритму, в который входит выделение отдельных операндов и определение их типов. В последнем случае должна производиться также необходимая проверка правильности кодирования операндов (количество операндов, допустимость типов).

Обнаружение литералов

Требует, как минимум, выделения операндов команды.

Листинг

Строка листинга печатается в конце каждой итерации обработки команды. Строка листинга 1-го прохода содержит: номер оператора, значение счетчика адреса (только для команд и директив, приводящих к выделению памяти), текст оператора. Листинг 1-го прохода не является окончательным, фактически он используется только для поиска ошибок, поэтому печатать его необязательно. Режим печати листинга 1-го прохода может определяться параметром Ассемблера или специальной директивой. После листинга программы может (опционно) печататься таблица символов.

Ошибки

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

Некоторые структуры данных 1-го прохода

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

Таблица директив содержит одну строку для каждой директивы Обработка каждой директивы происходит по индивидуальному алгоритму, поэтому параметры обработки нельзя представить в виде данных единого для всех директив формата. Для каждой директивы в таблице хранится только идентификация (имя или адрес, или номер) процедуры Ассемблера, выполняющей эту обработку. Некоторые директивы обрабатываются только на 1-м проходе, некоторые — только на 2-м, для некоторых обработка распределяется между двумя проходами.

Таблица символов является основным результатом 1-го прохода Ассемблера. Каждое имя, определенное в программе, должно быть записано в таблице символов. Для каждого имени в таблице хранится его значение, размер объекта, связанного с этим именем и признак перемещаемости/неперемещаемости. Значением имени является число, в большинстве случаев интерпретируемое как адрес, поэтому разрядность значения равна разрядности адреса.

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

Таблица литералов содержит запись для каждого употребленного в модуле литерала. Для каждого литерала в таблице содержится его символьное обозначение, длина и ссылка на значение. Литерал представляет собой константу, записанную в памяти. Обращение к литералам производится так же, как и к именам ячеек программы. По мере обнаружения в программе литералов Ассемблер заносит их данные в так называемый литеральный пул. Значение, записываемое в таблицу литералов является смещением литерала в литеральном пуле. После окончания 1-го прохода Ассемблер размещает литеральный пул в конце программы (то есть, назначает ему адрес, соответствующий последнему значению счетчик адреса) и корректирует значения в таблице литералов, заменяя их смещениями относительно начала программы. После выполнения этой корректировки таблица литералов может быть совмещена с таблицей символов.

Структура таблиц Ассемблера

Структура таблиц Ассемблера выбирается таким образом, чтобы обеспечить максимальную скорость поиска в них.

Таблицы команд и директив являются постоянной базой данных. Они заполняются один раз — при разработке Ассемблера, а затем остаются неизменными.

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

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

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

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

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

Эти же соображения относятся и к другим таблицам, формируемым Ассемблером в процессе работы. При больших размерах таблиц и размещении их на внешней памяти могут применяться и более сложные (но и более эффективные) методы их организации, например — B+-деревья.

Двухпроходный Ассемблер — второй проход

Обычно 2-й проход Ассемблера читает исходный модуль с самого начала и отчасти повторяет действия 1-го прохода (лексический разбор, распознавание команд и директив, подсчет адресов). Это, однако, скорее дань традиции — с тех времен, когда в вычислительных системах ощущалась нехватка (или даже полное отсутствие) внешней памяти. В те далекие времена колода перфокарт или рулон перфоленты, содержащие текст модуля, вставлялись в устройство ввода повторно. В системах с эволюционным развитием сохраняются перфокарты и перфоленты (виртуальные), так что схема работы Ассемблера — та же. В новых системах Ассемблер может создавать промежуточный файл — результат 1-го прохода, который является входом для 2-го прохода. Каждому оператору исходного модуля соответствует одна запись промежуточного файла, и формат этой записи приблизительно такой:

Текст исходного оператора нужен только для печати листинга, Ассемблер на 2-м проходе использует только первые 4 поля записи. Первое поле позволяет исключить строки, целиком состоящие из комментария. Второе поле позволяет избежать подсчета адресов, третье — поиска мнемоники в таблицах. Основная работа 2-го прохода состоит в разборе поля операндов и генерации объектного кода.

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

u        регистр;

u        непосредственный операнд;

u        адресное выражение.

Виды адресных выражений зависят от способов адресации вычислительной системы, некоторые (возможно, наиболее типовые) способы адресации:

u        абсолютный адрес;

u        [базовый регистр]+смещение (здесь и далее квадратные скобки означают «содержимое того, что взято в скобки»);

u        [базовый регистр]+[индексный регистр]+смещение;

u        имя+смещение;

u        литерал.

Адресное выражение моет содержать арифметические операции, соображения, касающиеся арифметики в этом случае — те же, что и в адресной арифметике языка C.

Имена в адресных выражениях должны заменяться на значения. Замена абсолютных имен (определенных в директиве EQU) очень проста — значение имени из таблицы символов просто подставляется вместо имени. Перемещаемые имена (метки и имена переменных) превращаются Ассемблером в адресное выражение вида [базовый регистр]+смещение. В таблице символов значения этих имен определены как смещение соответствующих ячеек памяти относительно начала программы. При трансляции имен необходимо, чтобы:

u        Ассемблер «знал», какой регистр он должен использовать в качестве базового;

u        Ассемблер «знал», какое значение содержится в базовом регистре;

u        в базовом регистре действительно содержалось это значение.

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

В Intel Ассемблер использует в качестве базовых сегментные регистры (DS при трансляции имен переменных, CS при трансляции меток). Для простой программы, состоящей из одной секции,

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

Сложная программа может состоять из нескольких секций, и в сегментном регистре может содержаться адрес той или иной секции, причем содержимое сегментного регистра может меняться в ходе выполнения программы. Загрузка в сегментный регистр адреса секции выполняется машинными командами:

MOV AX,секция

MOV сегментный_регистр,AX

Для того, чтобы Ассемблер знал, что адрес секции находится в сегментном_регистре, применяется директива:

ASSUME сегментный_регистр:секция

Далее при трансляции имен Ассемблер превращает имена в адресные выражения вида

[сегментный_регистр]+смещение в секции

Отмена использования сегментного регистра задается директивой:

ASSUME сегментный_регистр:NOTHING

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

MOV AX,секция

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

Более гибкая система базовой адресации применяется в S/360, S/370, S/390. В качестве базового может быть использован любой регистр общего назначения. Директива:

USING относительный_адрес,регистр

сообщает Ассемблеру, что он может использовать регистр в качестве базового, и в регистре содержится адрес — 1-й операнд. Чаще всего относительный_адрес кодируется как * (обозначение текущего значения счетчика адреса), это означает, что в регистре содержится адрес первой команды, следующей за директивой USING. Занесение адреса в базовый регистр выполняется машинной командой BALR. Обычный контекст определения базового регистра:

BALR регистр,0

USING *,регистр

С такими операндами команда BALR заносит в регистр адрес следующей за собой команды.

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

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

Директива

DROP регистр

отменяет использование регистра в качестве базового.

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

Выше мы говорили, что Ассемблер «знает» базовый регистр и его содержимое. Это «знание» хранится в таблице базовых регистров. Обычно таблица содержит строки для всех регистров, которые могут быть базовыми и признак, используется ли регистр в таком качестве. Формат строки таблицы:

Алгоритм выполнения 2-го прохода представлен на рисунке. Мы исходили из того, что 2-й проход использует промежуточный файл, сформированный 1-м проходом. Если же 2-й проход использует исходный модуль, то алгоритм должен быть расширен лексическим разбором оператора, распознаванием мнемоники и подсчетом адресов — так же, как и в 1-м проходе.

F        Блок1: Начало 2-го прохода ассемблирования.

F        Блок2: Начальные установки:

u        создание пустой таблицы базовых регистров;

u        открытие промежуточного файла исходного модуля;

u        установка в FASLE признака окончания

F        Блок3: Признак окончания TRUE?

F        Блок4: Считывание следующей записи промежуточного файла.

F        Блок5: Если запись промежуточного файла описывает комментарий, переход на печать строки листинга.

F        Блок6: Выясняется, содержит оператор команду или директиву

F        Блок7: Если оператор содержит команду, формируется байт кода операции (код выбирается из таблицы команд) в объектном коде.

F        Блок8: Выделение следующего элемента из списка операндов с удалением его из списка и с проверкой, не обнаружен ли при выделении конец списка операндов?

F        Блок9: Если конец не обнаружен, обрабатывается выделенный операнд. Проверяется, не превысило ли число операндов требуемого для данного типа команды (выбирается из таблицы команд)

F        Блок10: Если число операндов превышает требуемое — формирование сообщения об ошибке

F        Блок11: Если число операндов правильное, распознается и проверяется тип операнда.

F        Блок12: Если тип операнда не распознан или недопустим для данной команды — формирование сообщения об ошибке.

F        Блок13: Есть ли в команде имя?

F        Блок14: Если в команде есть имя, оно ищется в таблице символов.

F        Блок15: Если имя в таблице символов не найдено — формирование сообщения об ошибке.

F        Блок16: Если найдено имя в таблице символов, оно переводится в «база-смещение»

F        Блок17: Если имени в команде нет, выполняется разбор и интерпретация операнда с проверкой правильности его кодирования.

F        Блок18: Если обнаружены ошибки в кодировании операнда — формирование сообщения об ошибке.

F        Блок19: Формируется код поля операнда и заносится в объектный код команды и обрабатывается следующий элемент списка операндов.

F        Блок20: Если обнаружен конец списка операндов, проверяется, не меньше ли число операндов требуемого для данного типа команды. Если число операндов соответствует требуемого, управление переходит на вывод объектного кода.

F        Блок21: Если число операндов меньше требуемого — формирование сообщения об ошибке

F        Блок22: Если обрабатываемый оператор является директивой, алгоритм разветвляется, в зависимости от того, какая это директива. При обработке любой директивы производится разбор и анализ ее операндов и (не показано на схеме алгоритма) возможно формирование сообщения об ошибке.

F        Блок23: Обработка директивы типа DD включает в себя:

u        выделение элементов списка операндов;

u        для каждого элемента — распознавание типа и значения константы;

u        генерация объектного кода константы;

u        обработка возможных коэффициентов повторения.

F        Блок24: Обработка директивы типа BSS может вестись точно так же, как и DD за исключением того, что вместо кода константы генерируются некоторые «пустые» коды. Однако, эти коды не нужны в объектном модуле, они могут не генерироваться, в этом случае должны предприниматься некоторые действия, формирующие «разрыв» в объектных кодах.

F        Блок25: Обработка директивы типа USING (ASSUME) включает в себя занесение в соответствующую строку таблицы базовых регистров значения операнда-адреса и установку для данного регистра признака использования.

F        Блок26: Обработка директивы типа USING (ASSUME) включает в себя занесение в соответствующую строку таблицы базовых регистров значения операнда-адреса и установку для данного регистра признака использования.

F        Блок27: Обработка директивы END устанавливает признак окончания в TRUE. При обработке этой директивы в объектный модуль также может заносится стартовый адрес программы — параметр директивы.

F        Блок28: Обработка прочих директив ведется по своим алгоритмам.

F        Блок29: После окончания обработки команды или директивы сформированный объектный код выводится в файл объектного модуля.

F        Блок30: Печать строки листинга. На эту точку также управление передается при выявлении ошибок. При наличии ошибки сообщение об ошибке печатается после строки листинга. Управление затем передается на считывание следующей записи промежуточного файла.

F        Блок31: После того, как установлен признак окончания работы формируются и выводятся в объектный модуль коды литерального пула, таблицы связываний и перемещений.

F        Блок32: Закрываются файлы, освобождается выделенная память.

F        Блок33: Работа Ассемблера завершается.

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

Некоторые дополнительные директивы

OGR
Установка адреса

Операндом директивы является числовая константа или выражение, вычисляемое при ассемблировании. Как правило, Ассемблер считает, что первая ячейка обрабатываемой им программы располагается по адресу 0. Директива ORG устанавливает счетчик адресов программы в значение, определяемое операндом. Так, при создании COM-программ для MS DOS программа начинается с директивы ORG 100H. Этим оператором резервируется 256 байт в начале программы для размещения префикса программного сегмента.

В абсолютных программах директива применяется для размещения программы по абсолютным адресам памяти.

START/
SECT

Начало модуля или программной секции. Операндом директивы является имя секции. Этой директивой устанавливается в 0 счетчик адресов программы. Программа может состоять из нескольких программных секций, в каждой секции счет адресов ведется от 0. При обработке этой директивы на 1-м проходе Ассемблер создает таблицу программных секций.

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

Директивы связывания

ENT
Входная точка

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

EXT
Внешняя точка

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

Эти директивы обрабатываются на 2-м проходе, и на их основе строятся таблицы связываний и перемещений.

Одно- и многопроходный Ассемблер

Мы показали, что в двухпроходном Ассемблере на 1-м проходе осуществляется определение имен, а на втором — генерация кода.

Можно ли построить однопроходный Ассемблер? Трудность состоит в том, что в программе имя может появиться в поле операнда команды прежде, чем это имя появится в поле метки/имени, и Ассемблер не может преобразовать это имя в адресное выражение, та как еще на знает его значение. Как решить эту проблему?

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

Если объектный модуль сохраняется в объектной памяти, то Ассемблер может отложить формирование кода для операнда — неопределенного имени и вернуться к нему, когда имя будет определено. При появлении в поле операнда команды неопределенного имени поле операнда не формируется (заполняется нулями). Таблица символов расширяется полями: признаком определенного/неопределенного имени, и указателем на список адресов в объектном модуле, по которым требуется модификация поля операнда.

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

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

После окончания прохода Ассемблер проверяет таблицу символов: если в ней остались неопределенные имена, выдается сообщение об ошибке.

Если объектный модуль выводится в файл по мере его формирования, алгоритм работы Ассемблера очень похож на предыдущий случай. Ассемблер не может при определении имени исправить уже сформированные и выведенные в файл операнды, но вместо этого он формирует новую запись объектного модуля, исправляющую старую. При загрузке будет сначала загружена в память запись с пустым полем операнда, но затем на ее место — запись с правильным полем операнда.

Для чего может понадобиться многопроходный Ассемблер? Единственная необходимость во многих проходах может возникнуть, если в директиве EQU разрешены ссылки вперед. Мы упоминали выше, что имя в директиве EQU может определяться через другое имя. В одно- или двухпроходном Ассемблере это другое имя должно быть обязательно определено в программе выше. В многопроходном Ассемблере оно может быть определено и ниже. На первом проходе происходит определение имен и составление таблицы символов, но некоторые имена остаются неопределенными. На втором проходе определяются имена, не определившиеся во время предыдущего прохода. Второй проход повторяется до тех пор, пока не будут определены все имена (или не выяснится, что какие-то имена определить невозможно). На последнем проходе генерируется объектный код.

по оформлению результатов:

Логические операции являются важным элементом в проектировании микросхем и имеют много общего в логике программирования. Команды AND, OR, XOR и TEST — являются командами логических операций. Эти команды используются для сброса и установки бит и для арифметических операций в коде ASCII. Все эти команды обрабатывают один байт или одно слово в регистре или в памяти, и устанавливают флаги CF, OF, PF, SF, ZF.

AND

В случае, если оба из сравниваемых битов равны 1, то результат равен 1; во всех остальных случаях результат — 0.

OR

В случае, если хотя бы один из сравниваемых битов равен 1, то результат равен 1; если сравниваемые биты равны 0, то результат — 0.

XOR

В случае, если один из сравниваемых битов равен 0, а другой равен 1, то результат равен 1; если сравниваемые биты одинаковы (оба — 0 или оба — 1) то результат — 0.

TEST

Действует как AND — устанавливает флаги, но не изменяет биты.

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

AND OR XOR 0101 0101 0101 0011 0011 0011

Результат:

0001 0111 0110

Для следующих несвязанных примеров, предположим, что AL содержит 1100 0101, а BH содержит 0101 1100:

1. AND AL,BH ;Устанавливает в AL 0100 0100

2. OR BH,AL ;Устанавливает в BH 1101 1101

3. XOR AL,AL ;Устанавливает в AL 0000 0000

4. AND AL,00 ;Устанавливает в AL 0000 0000

5. AND AL,0FH ;Устанавливает в AL 0000 0101

6. OR CL,CL ;Устанавливает флаги SF и ZF

Примеры 3 и 4 демонстрируют способ очистки регистра. В примере 5 обнуляются левые четыре бита регистра AL. Хотя команды сравнения CMP могут быть понятнее, можно применить команду OR для следующих целей:

1. OR CX,CX ;Проверка CX на нуль JZ ... ;Переход, если нуль

2. OR CX,CX ;Проверка знака в CX JS ... ;Переход, если отрицательно

Команда TEST действует аналогично команде AND, но устанавливает только флаги, а операнд не изменяется. Ниже приведено несколько примеров:

1. TEST BL,11110000B ;Любой из левых бит в BL JNZ ... ; равен единице?

2. TEST AL,00000001B ;Регистр AL содержит JNZ ... ; нечетное значение?

3. TEST DX,OFFH ;Регистр DX содержит JZ ... ; нулевое значение?

Еще одна логическая команда NOT устанавливает обpатное значение бит в байте или в слове, в регистре или в памяти: нули становятся единицами, а единицы — нулями. В случае, если, например, pегистр AL содержит 1100 0101, то команда NOT AL изменяет это значение на 0011 1010. Флаги не меняются.

Команда NOT не эквивалентна команде NEG, которая меняет значение с положительного на отрицательное и наоборот, посредством замены бит на противоположное значение и прибавления единицы.

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

u        обрабатывают байт или слово;

u        имеют доступ к регистру или к памяти;

u        сдвигают влево или вправо;

u        сдвигают на величину до 8 бит (для байта) и 16 бит (для слова)

u        сдвигают логически (без знака) или арифметически (со знаком).

Значение сдвига на 1 может быть закодировано как непосредcтвенный операнд, значение больше 1 должно находиться в регистре CL.

Команды сдвига

При выполнении команд сдвига флаг CF всегда содержит значение последнего выдвинутого бита.

Существуют следующие команды cдвига:

SHR ;Логический (беззнаковый) сдвиг вправо

SHL ;Логический (беззнаковый) сдвиг влево

SAR ;Арифметический сдвиг вправо

SAL ;Арифметический сдвиг влево

Следующий фрагмент иллюстрирует выполнение команды SHR:

MOV CL,03 ; AX:

MOV AX,10110111B ; 10110111

SHR AX,1 ; 01011011 ;Сдвиг вправо на 1

SHR AX,CL ; 00001011 ;Сдвиг вправо на 3

Первая команда SHR сдвигает содержимое регистра AX вправо на 1 бит.

Выдвинутый в результате один бит попадает в флаг CF, а самый левый бит регистра AX заполняется нулем. Вторая команда cдвигает содержимое регистра AX еще на три бита. При этом флаг CF последовательно принимает значения 1, 1, 0, а в три левых бита в регистре AX заносятся нули.

Рассмотрим действие команд арифметического вправо SAR:

MOV CL,03 ; AX:

MOV AX,10110111B ; 10110111

SAR AX,1 ; 11011011 ;Сдвиг вправо на 1

SAR AX,CL ; 11111011 ;Сдвиг вправо на 3

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

При сдвигах влево правые биты заполняются нулями. Таким обpазом, результат команд сдвига SHL и SAL индентичен.

Сдвиг влево часто используется для удваивания чисел, а сдвиг вправо — для деления на 2. Эти операции осуществляются значительно быстрее, чем команды умножения или деления. Деление пополам нечетных чисел (например, 5 или 7) образует меньшие значения (2 или 3, соответственно) и устанавливает флаг CF в 1. Кроме того, если необходимо выполнить сдвиг на 2 бита, то использование двух команд сдвига более эффективно, чем использование одной команды с загрузкой регистра CL значением 2.

Для проверки бита, занесенного в флаг CF используется команда JC (переход, если есть перенос).

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

ROR ;Циклический сдвиг вправо

ROL ;Циклический сдвиг влево

RCR ;Циклический сдвиг вправо с переносом

RCL ;Циклический сдвиг влево с переносом

Следующая последовательность команд иллюстрирует операцию циклического сдвига ROR:

MOV CL,03 ; BX:

MOV BX,10110111B ; 10110111

ROR BX,1 ; 11011011 ;Сдвиг вправо на 1

ROR BX,CL ; 01111011 ;Сдвиг вправо на 3

Первая команда ROR при выполнении циклического сдвига переносит правый единичный бит регистра BX в освободившуюся левую позицию. Вторая команда ROR переносит таким образом три правых бита.

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

Рассмотрим пример, в котором используются команды циклического и простого сдвига. Предположим, что 32-битовое значение находится в регистрах DX:AX так, что левые 16 бит лежат в регистре DX, а правые — в AX. Для умножения на 2 этого значения возможны cледующие две команды:

SHL AX,1 ;Умножение пары регистров

RCL DX,1 ; DX:AX на 2

Здесь команда SHL сдвигает все биты регистра AX влево, причем самый левый бит попадает в флаг CF. Затем команда RCL сдвигает все биты регистра DX влево и в освободившийся правый бит заносит значение из флага CF.

по выбору средств:

MASM, TASM

Литература:

  1. Алгоритмизация и программирование: учебное пособие (ГРИФ) // Канцедал С.А.  – М.: ИТ Форум: ИНФРА – М, 2010. – 252с.
  2. Операционные системы, среды и оболочки. Учеб. пособие// Партыка Т. Л., Попов И. И. -2-е изд., испр. и доп., - М.: Форум, 2010. - 528с.
  3. Программирование на языках высокого уровня: учебное пособие // Голицына О.Л., Попов И.И. – М.: Форум, 2010. – 496с.

Тема: Тема 1.3 Разработка, отладка и тестирование программ для многозадачных операционных системы (ОС) на примере OC Windows.

Цель ВСР: в результате работы обучающиеся должны уметь разрабатывать программы на Borland C++ Builder, подбирать аппаратную реализацию для разработанных программ и составлять инструкции по использованию подобных разработок.

Количество задач

Характер задачи (обязательный, рекомендательный)

Норма времени

(в часах по рабочей программе)

Срок выполнения (в неделях)

Форма представления материала

(по каждой задаче)

Форма контроля каждой задачи

№1

№2

№3

Обязательное

Обязательное

Рекомендательное

30

2 недели

2 недели

3 недели

Листинг*.c

Э3, *.dsn

Инструкция

Компиляция

Моделирование

Защита

Задание

№1 Разработка программы на языке Borland C++ Builder по индивидуальному заданию на основании типовых производственных задач (с комментариями в листинге построчно).

№2 Моделирование аппаратной части для выполнения разработанной программы.

№3 Разработка инструкции по использованию программных и аппаратных средств реализации типовых производственной задачи.

Рекомендации

по выполнению ВСР:

Запустите приложение Borland C++, для чего нажмите кнопку "Пуск" на панели задач и выберите "Программы" - > " Borland C++ 5.02" - > Borland C++.

В случае правильного выполнения указания загружается IDE (Integrated Development Environment – интегрированная среда разработки) (рис. 1). IDE является оболочкой, объединяющей все необходимые для программирования средства: компилятор, транслятор, отладчик и т. д.

Рис. 1

Оболочка снабжена рядом средств, упрощающих написание и отладку программ: это Help hints (краткие пояснения), система Неlp (справка), SpeedBar (оперативная панель) и SpeedMenus (оперативное меню).

Получить доступ к возможностям IDE можно с помощью меню и кнопок оперативной панели SpeedBar - при этом в IDE появляются новые окна. Пояснения Help hints появляются в строке состояния (горизонтальная полоса серого цвета в нижней части IDE). Это – краткие комментарии ваших действий. При передвижении указателя мыши по командам меню в строке состояния отображается краткое описание соответствующей команды. Если открываете проект, пояснения помогают вам в выборе нужных действий.

Чтобы получить более подробную вспомогательную информацию, нажмите клавишу < F1 >. Для того чтобы быстро найти в справочной системе описание какой-либо команды, присутствующей в программе, достаточно выделить её и нажать < F1 >.

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

Если щелкнуть на окне правой кнопкой мыши, появится оперативное меню SpeedMenu, которое отражает набор самых распространенных действий, выполняемых с отдельным окном.

Редактирование файлов

Основой любой программы является "source code" или исходный код – текст программы, набранный в любом текстовом редакторе, например, "Блокноте", встроенном в Windows. IDE Borland C++ содержит собственный редактор, достоинством которого является возможность одновременного редактирования нескольких файлов исходного кода, при этом каждый из них занимает в IDE собственное окно. Однако основное преимущество этого редактора – контроль простых синтаксических ошибок в реальном времени, значительно ускоряющий процесс отладки програмы.

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

Создать новый файл. Выберите команду File->New->Text Edit. Новому файлу по умолчанию присваивается некоторое имя. При сохранении файла вы заменяете это имя на более подходящее.

Открыть уже существующий файл. Выберите команду
File->Open. Выберите имя файла, который вы хотите отредактировать.

Для сохранения результатов работы с файлом "source code" можно воспользоваться одним из приведенных ниже способов.

Сохранить файл. Выберите File->Save

Сохранить файл под новым именем. Выберите File->Save As. Наберите имя, которое хотите дать файлу и щелкните на кнопке OK.

Сохранить все файлы, в которые вносились изменения. Выберите File->Save All.

При наборе программ может довольно часто возникнуть необходимость отыскать в своём файле тот или иной блок кода. Для поиска фрагмента текста используется команда Search->Find. Если нужно найти текст и заменить его, воспользуйтесь командой Search->Replace.

Компиляция и ошибки при компиляции

Неотъемлемым этапом создания программы является компиляция – процесс преобразования исходного кода в машинный код. В результате получается объектный файл, "построив" который можно получить исполняемый файл. Чтобы запустить процесс компиляции выберите Project->Compile. Если вы хотите скомпилировать, построить и сразу же запустить программу, просто щелкните на кнопке Run (рис. 2).

Команда Project->Compile осуществляет компиляцию исходного кода, которая заключается в проверке синтаксических ощибок, присутствующих в коде на момент ее начала. Процесс компиляции не завершается созданием законченной программы. Если файл успешно скомпилирован, результатом будет лишь объектный файл с расширением .obj.

При построении (команда Debug->Run) объектный файл преобразуется в исполняемый файл, структура которого зависит от операционной системы, под управлением которой он будет работать. Объектный файл – не зависит от типа операционной системы, как и исходный код, исполняемый файл – зависим.

Если компилятор обнаруживает ошибку, он выводит на экран окно сообщений Message со списком ошибок. Щелкнув на ошибке, можно перейти в ту строку, где эта ошибка расположена. Для того чтобы программа была скомпилирована, надо исправить все ошибки. Компилятор разделяет ошибки на два типа – синтаксические (Errors), причиной которых является нарушение синтаксиса Си-программы и смысловые (Warnings), не препятствующие компиляции кода, однако нередко приводящие к искажению значений переменных в процессе работы прораммы.

Если вы допустили синтаксическую ошибку, придер-живайтесь следующих простых правил.

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

2. Проверьте символы ";" и "}" – возможно вы где-то пропустили один или, наоборот, поставили лишний.

3. Сообщение с текстом "cannot convert ... to ..." означает обычно, что вы пытаетесь приписать переменной значение другого типа. Например, у вас переменная, которая является целым числом (тип int), а вы пытаетесь превратить её в строку (тип char*).

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

5. Порой одной незначительной ошибки достаточно, чтобы привести к тому, что компилятор обнаружит сотни проблем. Например, если для заголовочного файла указать неправильный путь, или упустить скобку при выделении тела main(), источником ошибки могут стать все строки вашей программы.

Смысловую ошибку иногда называют предупреждением (англ. "warning" – предупреждение). Предупреждение появляется в том случае, когда компилятор понимает, что вы делаете, но считает, что делать этого не следует. Например, вы создаете переменную, которой никогда не присваивается никакого значения, или используете переменную, не присвоив ей значения. Рекомендуется обращать внимание на предупреждения. Иногда они появляются только потому, что компилятор излишне осторожен, но чаще всего причина все-таки в том, что программист невнимателен. Последствием неустранения предупреждений рано или поздно окажется длительная отладка программы непременно с применением отладчика.

Отладка программы

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

Рис. 2

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

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

Stepping and tracing (Пошаговое выполнение и отслежи-вание). Позволяют выполнять программу построчно и видеть результат каждого действия, поэтому можно заметить, когда случится что-нибудь непредвиденное.

Inspectors (Инспекторы). Выводят на экран значения переменных. Когда компилятор останавливается в точке прерывания или проводит построчное выполнение программы, окна инспектирования позволяют просмотреть значения всех используемых переменных.

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

Точки прерывания

Теперь немного подробней об этих средствах отладки. Точка прерывания используется в том случае, когда нужно остановиться на определенной строке. Чтобы установить точку прерывания в выбранной строке, щелкните на отступе (области серого цвета) слева от этой строки. Чтобы убрать точку прерывания, щелкните там еще раз. Со строки снимается выделение красным цветом, исчезает пиктограмма со знаком "стоп". Следует обратить внимание, что щелчок правой кнопкой мыши вызывает контекстное меню, с помощью которого можно устанавливать и убирать точки прерывания. Если вы не помните точно, есть ли в вашей программе точки прерывания, можно воспользоваться командой View->Breakpoint. Она выводит на экран диалоговое окно, в котором показаны все активные точки прерывания.

Трассировка и пошаговая отладка

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

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

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

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

Чтобы приступить к пошаговому выполнению, следует нажать < F8 > или щелкнуть на пиктограмме (рис. 2). Для трасси-ровки, надо нажать < F7 > или щелкнуть по соответствующей кнопке SpeedBar (рис. 2). Для выполнения каждого шага необходимо повторно нажимать F7 или F8. Для прекращения пошагового выполнения нажмите < ctrl–F2 >.

Инспектор

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

1) выберите в редакторе имя объекта, установив на него курсор;

2) щелкните правой кнопкой мыши, чтобы вызвать оперативное меню SpeedMenu;

3) Выберите в нем команду Inspect (Инспектировать).

Появляется инспектор и показывает значение объекта. Пример окна показан на рис. 3. По мере выполнения программы окно инспектора обновляется.

Рис. 3

Существует возможность изменения переменных во время её изучения. Делается это так.

  1. В окне инспектора щелкните правой кнопкой мыши на имени переменной.
  2. Выберите команду Change.
  3. Наберите новое значение.
  4. Подтвердите изменение.

Наблюдатель (Watcher)

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

Рис. 4

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

  1. Выполните команду View->Watch.
  2. Щелкните правой кнопкой по окну Watches, чтобы вызвать подменю.
  3. Выберите в нем Add Watch..., для добавления в список наблюдения новой переменной.

по оформлению результатов:

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

char * strcpy(char *, char * ) // копирует в первую строку вторую, возвращая указатель на первую;

char * strcat(char *, char * ) // выполняет конкатенацию(объединение) двух строк, возвращая указатель на результирующую;

int strcmp(const char *, const char *) // сравнивает строки, возвращая число больше ноля, если первая строка больше второй и наоборот. Ноль возвращается в случае равенства строк.

Рассмотрим пример программы, эквивалентный библиотечной функции strlen() определяющей длины строки:

#include

char cString1[100];

void main(void)

{int i=0;

        scanf("%s", cString1);

        while(cString1[i]!='\0')

                i++;

}

по выбору средств:

Borland C++Builder

Литература:

  1. Алгоритмизация и программирование: учебное пособие (ГРИФ) // Канцедал С.А.  – М.: ИТ Форум: ИНФРА – М, 2010. – 252с.
  2. Операционные системы, среды и оболочки. Учеб. пособие// Партыка Т. Л., Попов И. И. -2-е изд., испр. и доп., - М.: Форум, 2010. - 528с.
  3. Программирование на языках высокого уровня: учебное пособие // Голицына О.Л., Попов И.И. – М.: Форум, 2010. – 496с.