Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


ВВЕДЕНИЕ В СИСТЕМНОЕ ПРОГРАММИРОВАНИЕ



ВВЕДЕНИЕ В СИСТЕМНОЕ ПРОГРАММИРОВАНИЕ

 

 

Конспект лекций

для студентов специальности 220200, 552800 по курсу «Системное программное обеспечение», 220300 по курсу «Лингвистическое и программное обеспечение»

 

 

 

 

 

Ижевск, 2003



АННОТАЦИЯ

Конспект лекций в сжатом виде дает важнейшие темы по курсу «Системное программное обеспечение»: процессы обмена информации и доступа к оперативной памяти; системная библиотека языка ПАСКАЛЬ; методы получения выполняемой программы; программирование на языке АССЕМБЛЕР; программирование на языке С.



СОДЕРЖАНИЕ

I . ОСНОВЫ ОБМЕНА ИНФОРМАЦИЕЙ В IBM PC.

НАЗНАЧЕНИЕ СИСТЕМНОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ СПО)   5

 ОС и языки программирования                                                                           5

ОБСЛУЖИВАНИЕ ВВОДА-ВЫВОДА                                                                         6

Организация ввода-вывода                                                                                   6

Способы управления ПУ                                                                                        6

БУФЕРНЫЙ ОБМЕН ИНФОРМАЦИЕЙ В ЯЗЫКАХ ПРОГРАММИРОВАНИЯ 9

3.1. Функции и команды по файловой обработке                                                     11

3.2. Пример обработки не типизированного файла                                                  11

УПРАВЛЕНИЕ И ДОСТУП К ОПЕРАТИВНОЙ ПАМЯТИ.                                   13

4.1. Распределение ОП на платформе IBM PC                                                         13

4.2. Методы обращения к памяти                                                                              13

Управление реальной памятью                                                                           15

II. БИБЛИОТЕКА DOS TURBO PASCAL.

БИБЛИОТЕКА DOS                                                                                                          18

5.1 Общая информация                                                                                               18

5.2. Регистры центрального процессора                                                                   20

5.3 Процедуры работы с файлами                                                                             23

5.4 Функции работы с магнитными носителями                                                     23

5.5. Обработка прерываний                                                                                        23

5.6. Другие возможности                                                                                            25

5.7. Некоторые прерывания платформы IBM PC                                                    25

5.8. Системные соглашения при использовании турбо Паскаль                           31

ОВЕРЛЕЙ                                                                                                                          32

Структура программного комплекса                                                                 32

Распределение памяти в оверлейной структуре                                               33

6.3. Пример программы с использованием оверлея                                                34

III . ПРОГРАММИРОВАНИЕ НА ВСТРОЕННОМ АССЕМБЛЕРЕ.

ВСТРОЕННЫЙ В TURBO PASCAL ASSEMBLER                                                   35

7.1. Общие положения                                                                                                35

Режимы адресации в Ассемблере                                                                       36

 Соответствие ординарных типов данных между языками программирования 36

Выражения для управления памятью                                                                37

Выражения в Ассемблере                                                                                    37

Команды Ассемблера                                                                                          38

7.7. Дополнительные атрибуты у подпрограмм на Turbo Pascal                           43

IV . СРАВНИТЕЛЬНОЕ ИЗУЧЕНИЕ ЯЗЫКА С НА ОСНОВЕ ТР.

ЯЗЫК ПРОГРАММИРОВАНИЯ С                                                                              45

8.1. Константы                                                                                                            45

8.2. Синтаксис С                                                                                                         46

8.3. Типы памяти переменных                                                                                  46

8.4 Структуры в С                                                                                                           47

8.5. Операции в выражениях                                                                                    47

8.6. Операторы языка Си                                                                                          49

8.7. Функции в языке Си                                                                                           50

8.8. Структура головной программы на языке Си                                                  51

8.9. Включаемые библиотеки                                                                                    51

Стандартные библиотеки                                                                                 52

ЛИТЕРАТУРА                                                                                                52

ПРИЛОЖЕНИЯ

ЭКЗАМЕНАЦИОННЫЕ ВОПРОСЫ                                                                   52

СТРУКТУРА ТЕХНИЧЕСКОГО ЗАДАНИЯ НА КУРСОВУЮ РАБОТУ  53

 



ОБСЛУЖИВАНИЕ ВВОДА-ВЫВОДА

Организация ввода-вывода

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

– внешние запоминающие устройства (жесткие, гибкие, лазерно-оптические диски и др.);

– устройства ввода информации (клавиатура, сканер, мышь, модем и др.);

– устройства вывода информации (монитор, принтер, графопостроитель и др.)

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

Организация ввода-вывода

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

Контроллер представляет собой устройство управления, приспособленное к заданному типу внешних устройств, например, контроллер жестких или гибких дисков. Главный интерес здесь заключается в том, чтобы разделить контроллер и устройство и связать устройства одного типа с одним единственным контроллером. В этом случае передача информации в каждый момент времени осуществляется только с одним устройством. На других устройствах в это время можно одновременно выполнять лишь те действия, которые не связаны с непосредственной передачей информации. В связи с этим мы можем наблюдать заметное замедление при обмене двух устройств, обслуживаемых одним контроллером. Попробуйте скопировать содержимое 5,25’-дискеты на 3,5’-дискету, которые подключены к единственному контроллеру гибких дисков. Чтобы избежать подобных неприятностей при работе с двумя жесткими дисками, их рекомендуют подключать по одному к контроллеру жестких дисков (их, как правило, бывает два). Разделение функций между контроллером и ПУ зависит от типа ПУ. Как правило, логические функции (соединение и синхронизация операций, передача сигналов об окончании работы) предоставляются контроллеру, а физические (передача) – устройству.

Совокупность контроллер – ПУ определяет интерфейс группы устройств. В системе невозможно обслуживание ПУ, которое подключено к контроллеру с отличным от предусмотренного для него интерфейса.

Способы управления ПУ

 

Понятие драйвера ПУ

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

– принимает запросы на обращение к ПУ;

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

– обрабатывает передаваемые ПУ прерывания;

– обнаруживает и обрабатывает случаи ошибок.

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

Драйвера одного и того же устройства для разных ОС различны.

 

Синхронный ввод-вывод

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

Синхронный ввод-вывод был стандартным для большинства ОС (например, для MS-DOS), которые работали на компьютерах с низкой производительностью процессора, для которых актуальность параллельной обработки была невелика. Увеличить производительность системы с такой организацией можно достаточно простым способом – снабдить ПУ собственным буфером памяти, в котором могут размещаться данные для вывода или ввода. Например, принтер HP LJ4P оснащен собственной памятью в объеме 2МБ. Передав необходимые для печати данные в эту память, пользовательская программа может продолжать свою работу.

Синхронный ввод и вывод информации можно осуществить использую предопределенные массивы Port и PortW.

Port [<Addr>]- осуществляет связь с портом. Порт имеет абсолютно точный адрес, состоящий из трех шестнадцатеричных цифр. Портом называется специальный адрес, по которому хранится, как правило регистр (входной / выходной) периферийного устройства.

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

Массив Port употребляется для написания системных программ без обращения к драйверам ОС.

a:=Port[$367];

Port W [...]- обращение к порту с помощью слова.

Необходимо абсолютно точно знать конструкцию порта. Если порт длиной 1 байт, а происходит обращение как к 2-х байтному, то за одно обращение происходит связь с 2-м портам, при этом адрес второго отличается на 1 от адреса, заданного в PortW.

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

Пример. Пусть по адресу $246 находится регистр устанавливающий периферийное устройство в готовность к передаче данного, если у него установить 3 бит. По адресу $247 находится порт данных, в который нужно передать байт информации, хранящийся в переменной DAT.

Var Dat,Port_dat:byte;

…………….

Begin

……..

Port_dat:=Port[$246];

Port[$246]:=Port_dat or 8;

Port[$247]:=Dat;

Port[$246]:=Port_dat;

……..

end.

Обратите внимание! Установка бита в порте $246 осуществляется через операцию логического сложения, что изменяет содержимое других битов порта.

По алгоритму обмена информации порты делятся на три группы:

1. Непосредственные порты обмена информацией. Как правило регистры управляющие работой периферийного устройства;

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

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

Пример работы с портами будет рассмотрен в курсе «Компьютерная графика» в разделе «Непосредственное программирование видеоадаптера»/1/.

Асинхронный ввод-вывод

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

Асинхронный ввод-вывод имеет важное преимущество перед синхронным – возможность повышения скорости работы приложений. Пока устройство занято пересылкой данных, приложение продолжает выполнять другую работу. Кто не выполнял так называемую фоновую печать документов в Word из под Windows? Но в обмен на достоинства асинхронный ввод-вывод требует большего объема программирования, а следовательно кода и занимаемой ОС памяти.

 

Буферный ввод-вывод

Т.к. скорости работы процессора и ПУ сильно различаются, то для повышения производительности вычислительной системы применяют буферизацию ввода-вывода. Для этого выделяют специальную зону в памяти – буфер для улучшения взаимодействия ПУ с программами пользователей. Отделяя работу процессора от работы периферии, надеются уменьшить время его пребывания в неактивном состоянии. Программы пользователей и ПУ передают информацию в буфер или из него. Чем больше размер буфера, тем эффективнее отделение процессора от периферии. Стремление не занимать слишком много под памяти привело к размещению буферов либо на диске (спулинг или свопинг), либо в виртуальной памяти.

Общие принципы обслуживания буферного ввода-вывода описываются следующими спецификациями:

– при обмене с ПУ используются записи фиксированного размера;

– размер буфера фиксирован и может вместить целое количество записей;

– для программы пользователя обмен с буфером имитируется ОС как обмен с ПУ, следовательно, должен сохраняться порядок передачи информации на хранение и изъятие между буфером и ПУ и ни одна запись не должна потеряться;

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

Буферный обмен данными может быть как синхронным, так и асинхронным.



Управление реальной памятью

 

Для непосредственного выполнения программ или обращения к данным необходимо, чтобы они размещались в основной памяти. Любая ОС, поддерживающая работу более одного пользователя, и как следствие, более одного процесса, должна обладать механизмом разделения основной памяти между совместно выполняющимися процессами. Многие мультипрограммные ОС разбивают память на разделы (partitions) с выделением каждому процессу своего раздела. Размер и расположение разделов могут быть либо заранее заданы (разделы фиксированного размера), либо назначаться динамически в процессе выполнения заданий (разделы переменного размера).

Рассмотрим несколько стратегий управления памятью на примере следующей последовательности заданий пользователей

Задание Длина (шестнадцатеричная)
1 A000
2 14000
3 A800
4 4000
5 E000
6 B000
7 C000
8 D000

Пусть объем доступной памяти предполагается равным 50 000 байт, а ОС занимает первые 10 000 байт (размеры и адреса даны в шестнадцатеричном виде).

 Разделы фиксированной длины

Допустим, что память, не занятая ОС состоит из четырех разделов: раздел 1 занимает 18000 байт, разделы 2 и 3 по 10000 байт, а раздел 4 – 8000 байт.

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

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

 Использование разделов переменного размера

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

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

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

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

Стратегия наиболее подходящего. Поступающее задание помещается в ту область, где ему наиболее “тесно”, так что остается минимальное неиспользуемое пространство.

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

Защита памяти

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

а) При помощи аппаратной поддержки вводятся два дополнительных граничных регистра, в которых будут содержаться начальный и конечный (или размер) адреса раздела текущего задания. Это регистры недоступны программам пользователя. ОС устанавливает граничные регистры, когда пользовательскому заданию назначается раздел. Во время операций контекстного переключения значения этих регистров автоматически сохраняется. Т.о. граничные регистры всегда содержат адреса начала и конца раздела, отведенному текущему активному процессу. При любом обращении к памяти аппаратура автоматически сверяет свой адрес, по которому идет обращение к памяти, с граничными регистрами. Если адрес находится вне раздела текущего задания, то обращение к памяти не производится и генерируется программное прерывание.

б) При помощи ключей. Каждому блоку памяти ставится в соответствие, как правило, 4-х битовый ключ защиты памяти (следовательно существуют 24=16 вариантов ключей). Каждый пользовательский процесс имеет поставленный ему в соответствие 4-х битовый идентификатор процесса, который хранится в слове состояния. Когда заданию выделяется какой-нибудь раздел, ОС присваивает ключам всех блоков памяти внутри этого раздела значение идентификатора процесса этого задания. При каждом обращении пользовательского процесса к памяти аппаратура сравнивает идентификатор процесса с ключом защиты адресуемого блока. Если значения этих полей не совпадают, то обращение к памяти не происходит и генерируется программное прерывание .

 

 

БИБЛИОТЕКА DOS

 

5.1 Общая информация

 

Библиотека DOS предназначена для работы системными средствами операционной системы DOS версии 3.0 и выше.

 

Все основные процедуры и функции делятся на следующие разделы:

1. Работа с системным таймером

2. Работа с файлами

3. Работа с прерываниями

4. Работа с операционной системой

 

ПРЕРЫВАНИЕМ называется специальная программа, которая находится постоянно во время сеанса в операционной системе и используется в процессе обмена ЦП и периферийного устройства или исключительной ситуации при работе ЦП.

 

Прерывания делятся на 3 основные группы:

1) Прерывания платформы;

2) Прерывания операционной системы;

3) Пользовательские прерывания.

 

Примечание. Пользовательские прерывания разрешены в операционной системе MS DOS и Windows 9x.

При использовании любых библиотек Turbo Pascal запрещено переопределять типы и использовать имена, совпадающие с именами или константами, входящими в библиотеку.

 

Группы констант. Атрибуты файлов.

1) Только для чтения. Установлен нулевой разряд. Значение 1

2) Скрытый файл. Установлен 1 разряд. Значение 2.

3) Системный файл. 2 разряд. Значение 4.

4) Метка тома - название диска, винчестера или дискеты. 3 разряд. Значение 8.

5) Директория (каталог). 4 разряд. Значение $10 (в шестнадцатеричной системе исчисления).

6) Архив. 5 разряд. Значение $20.

 

Другие разряды в MS DOS не используются.

 

Примечание. Архивный файл, как правило, относятся к любому файлу, за исключением метки тома и директории.

Скрытый системный файл: значение =$6.

 

Типы.

- Регистры центрального процессора

 

Type Registers = record

Case Integer of

0:(AX, BX, CX, DX, BP, SI, DI, DS, ES, flags : word);

1:(AL, AH, BL, BH, CL, CH, DL, DH : byte)

End;

 

- Структура для поиска файлов

 

SearchRec = record

File:array [1..21] of byte;

Attr:byte;         {атрибут файла}

Time:longint;    {упакованное дата и время создания файла}

Size:longint;     {длина файла}

Name:string[12] {имя (8 байт-имя, 3 байта - расширение)}

End;

 

- Запись - распакованные дата и время

 

DateTime = record Year, Month, Day, Hour, Min, Sec:word

End;

 

5.2. Регистры центрального процессора.

 

Первый процессор фирмы INTEL имел длину разрядной сетки 8 бит и только 10 регистров; начиная с процессора 8086i регисты стали иметь длину 16 бит; начиная с процессора 80386i регистры стали иметь длину 32 бита. Итак все регистры делятся на следующие группы:

1. Основные регистры.

2. Регистры статуса и управления вычислений.

3. Сегментные регистры.

 

5.2.1. Основные регистры:

 

1-ый регистр носит название А-регистр аккумулятор.

 

 

ЕАХ

31   15 АХ    0          0-7 регистр AL

  АН AL

        8-15 регистр АН


32 разрядный регистр называется расширенный регистр ЕАХ.

Т. к. В ТР рассматриваются только команда 286 процессора, то для применения доступны только регистры AL,AH и АХ.

В ТР в тексте ассемблера не рекомендуется употреблять индификаторы с именами регистров. В ассемблерном коде эти имена будут игнорироваться и обращение будет к регистрам центрального процессора.

1. Регистр базы: BH, BL, BX, EBX.

2. Регистр счетчика: CH, CL ,CX ECX.

3. Регистр данных: DH, DL, DX, EDX.

4. Указатель базы ВР: Base Point.

В отличии от предыдущих регистров, регистр ВР 16-разрядный и не делится на младший и старший байты.

5. Индекс источника SI: 32-разрядный ESI.

Структура аналогична (4).

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

6. индекс приемника DI: EDI.

Употребляется для хранения адреса массива, для выдачи данных.

7. Указатель стека: ESP Stack Pointer.

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

 

5.2.2. Регистры статуса и управления вычислений.

 

31                               17 16   14 13 12 12 10 9 8 7 6   4   2 1 0
                                VM RT   NT IO IO PL OF II IF SF ZF   AF   PF   CF

1. Регистр flags - 16-разрядный EFlags - 32-разрядный.

 

Для процессора 386.

Статусные флаги:

             CF -перенос;

             PF-четность;

             AF -вспомогательный перенос:

             ZF-нуль;

             SF-знак;

             OF-переполнение;

2. Управление процессом вычисления.

Используется для управления отладочным режимом.

DF-декремент, увеличение.

TF-ловушка.

3. Системные флаги:

Устанавливаются в процессе выполнения следующих команд ассемблера.

       VM-виртуальный режим;

       RT-возобновление задачи;

       NT-вложенная задача;

       IOPL-уровень привилегии прерывания ввода-вывода;

       IF-флаг разрешения прерывания;

В ТР во встроенном ассемблере из данной группы регистров анализируются только последние 2.

CF-установлен в “1”, если в результате операции был перенесен разряд из старшего бита в результате операции.

PF-установлен в “1”, если в результате операции получилось четное число.

AF-аналогичен флагу CF, но устанавливается для двоичной и десятеричной арифметики.

ZF-результат операции равен нулю.

SP- установлен в “1” старший разряд в результате операции

TF- установлен в “1” для отладочного режим только для процессоров 386 и выше.

IF-если он установлен в “1”, то запрещены другие прерывания.

DF-установлен в “1” если выполняется последовательность команд от старшего адреса к младшему.

OF- установлен в “1” если произошел процесс 1 из старшего разряда, но не хватило разрядной сетки для результата вычсления.

IOPL-хранит двубитный номер рапрв прерывания. Прерывания с максимальной рплыврпшр имеет номер 0,а с минимальной -3.

NT- установлен в “1”, если программа выполняет программу, вызванную из другой программы.

RT- установлен в “1”,если программист отменяет обработку особых ситуаций и возвращает управление программе.

VM- установлен в “1” в режиме многозадачности.

4. Указатель команд IP: EIP.

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

 

5.2.3. Сегментные регистры.

 

Служат для хранения адресов основных частей программы.

1. CS-регистр - code segment - сегмент кода.

Часть программы, в которой хранятся команды для выполнения.

ECS - запрещен для программирования.

2. DS - data segment - сегмент данных.

Хранит адрес начала данных в программном коде.

3. SS - stack segment - сегмент стека.

ESS - запрещен для программирования.

Дополнительные сегментные регистры: ES, FS, GS. Используются для дублирования соответствующих регистров.

 

5.3 Процедуры работы с файлами

 

Поиск файла в каталоге осуществляется с помощью процедуры

FindFirst (Path:PathStr; Attr:byte; var F:SearchRec);

{Path – путь к директории; Attr – атрибут файла; F – первый найденный файл.}

Если файл не найден, то переменная DosError не равна 0.

Следующий файл можно найти используя

FindNext (var F:SearchRec);

Процедуру можно использовать только после употребления FindFirst. Если дополнительных файлов нет, то переменная DosError не равна 0.

Кроме этих двух процедур пользователь имеет возможность прочитать различные параметры о любом используемом в программе файле. !!!Файл предварительно должен быть назначен.

Прочитать параметры (атрибут) файла.


SwapVectors

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

 

 

 

Пусть нам надо написать программу по обработке данных с клавиатуры, т. е. при прерывании с номером $16 должна работать не системная программа, а наша.

Пусть наша программа располагается по адресу nnnn : kkk, спроектируем программу на TP, одновременно с нашей программой по адресу: WNNN : NNNN располагается драйвер клавиатуры TP, по адресу yyyy:yyyy располагается драйвер обработки клавиатуры ОС и по адресу: xxxx:xxxx – драйвер клавиатуры платформы.

Для того, чтобы кроме нашей программы успешно работали другие программы ОС до выполнения нашей должны быть сохранены адреса программ обработчиков того же прерывания.

Такая процедура называется – сохранение вектора прерывания, где под вектором понимается адрес в оперативной памяти, с которого начинается предыдущая программа обработки прерывания.

В нашем случае до выполнения нашей программы вектор прерывания должен быть сохранён 3 раза. Для различных устройств такая последовательность может быть 1-3.

Для сохранения старого значения адреса программы в библиотеке Dos используется процедура: GetVect ( Intr : byte ; var P : pointer); Intr – номер прерывания, Р – указатель на адрес программы прерывания.

Для установки собственного драйвера используется следующая процедура: SetIntVec ( Intr : byte ; var P : pointer ); Intr - № прерывания, которое будет обрабатываться программой, Р – адрес подпрограммы обработки прерывания.

Адрес вычисляется аналогично адресу любой переменной.

Пример 1 .

Написать программу по установки монитора в режим 320х200 точек с использованием 256 цветов. Прерывания вызывать используя библиотеку DOS.

 

Uses dos;

Var R:Registers;

Begin

SwapVectors;

R.ah:=0;

R.al:=$13;

Intr($10,R);

SwapVectors;

End.

 

Пример 2.

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

 

Uses dos;

Procedure my_pixel( x,y : word; Color : byte);

Var R:Registers;

Begin

SwapVectors;

R.Ah:=$C;

R.Al:=Color;

R.Cx:=x;

R.dx:=y;

Intr($10,R);

SwapVectors

End;

 

 

5.6. Другие возможности.

 

Сделать программу резидентной: Keep ( ExitCode : word ); Употребление данной процедуры внутри программы приводит к тому, что при запуске программы она не снимается после окончания выполнения и постоянно находится загруженной в ОП.

ExitCode – значение передаётся в системную переменную EwdLevel после прохождения загруженной программы.

Выполнить загрузочный модуль внутри программы.

Exec ( Path , Com : String ), Path – полный путь к выполняемой программе, Com – параметры для выполнения программы.

Имя программы должно быть с расширением. Для успешного выполнения программы необходимо увеличить размер списка и кучи » в 2 раза больше чем в стандартных установках TP. Правильность выполнения необходимо анализировать системной переменной DosError.

Возвратить значение системной переменной ErrorLevel. DosExitCode : word;

Процедуры обработки прерывания Ctrl+Break, Ctrl+C.

При стандартной проектировании на ТР под Ms-Dos нажатие этих клавиш приводит к снятию программы. У программиста в библиотеке Dos имеются средства по отмене данного действия, это производится с помощью SetBreak (Code: Boolean).

Code = 1 выполняется стандартное действие, иначе программа на эти клавиши не реагирует. GetBreak (var Code: boolean);

 

5.7. Некоторые прерывания платформы IBM PC.

 

$10 – дисплей, функция в АН.

1. АН = 0 – режим VGA и ниже.

AL = номер режима ( 13 для 320*200*256 VGA).

 

2. АН = С установить pixel. Для графических режимов (VGA и ниже)

AL – цвет пиксела (в зависимости от видео режима)

СХ – координаты по оси Х

DX – координаты по оси Y

3. AH = D – прочесть пиксел

СХ – координаты по оси Х

DX – координаты по оси Y

Возврат из прерывания в регистре AL – цвет пикселя.

4. AH = F – прочитать номер видеорежима.

возврат из прерывания AL – номер, АН – количество символов в строке, в ВН – номер текущей видеостраницы, для режимов, в которых используется несколько видеостраниц. В текстовом режиме 8 страниц.

5. АН =1А – чтение или запись конфигурации VGA, если чтение регистра AL = 0, если запись, то AL = 1.

Для нормальной работ в регистре ВН записывается номер устройства при чтении из данного регистра возвращается тип адаптера: 0 – графического адаптера нет, 1 – MDA, 2 – CGA, 3, 4 – EGA, 5 – Mono EGA, 6 – PGC, 7 – mono VGA, 8 – VGA, A, B, C – MCGA.

6. АН=1С сохранить или восстановить значение в виде регистров адаптера VGA. AL = 0 – чтение, AL = 1 – запись.

По адресу ES:DI должна располагаться информационная структура длиной в 1 кБайт, в которую будут записаны (будут считаны) значения регистров адаптеров VGA.

 

7. АН= 4Fh Все функции VBE вызываются с регистром AH = 4Fh. Регистр AL используется для указания, какая функция VBE будет выполнена. При этом регистр BL в исключительных ситуация будет указывать специфическую подфункцию.

 

Функции 00h-0Fh зарезервированы для стандартных функций VBE. Функции 10h-FFh зарезервированны для поддержки дополнительных спецификаций VBE.

 

Результат выполнения функции возвращается через регистр AX :

       AL == функция не поддерживается

       AL <> 4Fh функция поддерживается

       AH == 00h вызов функции выполнен успешно

       AH == 01h вызов функции провален

AH == 03h функция не поддерживается в текущей конфигурации аппаратного обеспечения

       AH == 03h вызов функции нелегален в текущем видеорежиме

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

1 в регистр AH записывается значение 4Fh

2 в регистр AL – 00h

3 es:[di] должен указывать на область памяти, выделенной под структуру VbeInfoBlock.

4 выполняется прерывание Int 10h

5 функция выполнена успешно, если регистр AH=0

 

Пример : допустим, что мы уже имеем переменную VIBlock типа VbeInfoBlock, тогда вызов процедуры  

будет выглядеть следущим образом 

       asm

       mov ax,4F00h

         les di,@VIBlock

       int 10h

       mov Result,ah          

       end;

 

ОВЕРЛЕЙ

 

Оверлейной структурой под управлением ОС MS-DOS называется специальный комплекс программ позволяющий экономить оперативную память при выполнении программы. Под управление ОС Windows оверлей называется динамическими библиотеками.

Для того чтобы сделать оверлейную программу в Turbo Pascal пользователь должен осуществить 2 этапа:

Построить структурную схему программы.

Определить в главной программе использование библиотеки overlay и задать опции управления в программах.

 


Выражения в Ассемблере

 

Префикс (операция) Описание
: Вычисление адреса, первое подвыпажение – сегмент адреса, второе – смещение адреса
[…] Косвенная адресация, указание на адрес. Выражение в скобках определяет адрес
+ - * / Арифметические операции, причем умножение и деление здесь нацело
& Обозначает переменную ТР. Например, если в выражении &CH, то будет использоваться не регистр СН, а переменная ТР с этим именем
word Возврат результата выражения, укороченного словом
byte Возврат результата выражения, укороченного байтом
offset Смещение адреса(возврат)
seg Возврат сегмента адреса
PTR Адрес ячейки памяти, аналогично […]
mod Остаток от деления
shl,shr Сдвиг влево, вправо
not Побитовое отрицание
and Логическое умножение
or Логическое сложение
xor Исключающее “или”
high Возвращает старшие 8 бит выражения в слово, следующее за операндом
type Возвращает размер в байтах получающегося выражения. Если вместо выражения используется константа, то возврат равен нулю
low Возвращает младшие 8 бит выражения в слово, следующее за операндом

 

Пример команды, двигающей циклический регистр АХ вправо на три разряда и записывающей результат в BX:

mov bx,ax shr 3

 

Допускается любое количество скобок (())()((())) в выражении.

Скобки определяют порядок вычисления выражения. По умолчанию операции идут в следующем порядке:

byte, word, low, high

*, /

+, -, логические операции, сдвиг, offset, seg, PTR

type

 

Команды Ассемблера

 

Команды общего назначения

MOV – переслать операнд2 в операнд1. После выполнения – содержимое флагов не меняется и перед выполнением – не анализируется.

 

MOVS – переслать операнд2 в операнд1, но теперь первый и второй операнды должны являться ячейками памяти. Т.е. должна использоваться косвенная адресация.

 

Пример, movs [es:di],[es:bx]

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

PUSH – имеет один операнд. Записывает операнд в стек.

При этом значение регистра SP увеличивается на 1. Операнд записывается по адресу SS : SP

POP – восстановить операнд из стека. Обратная команда PUSH. Значение SP уменьшается на 1. Операнд берется по адресу SS : SP.

PUSHA – операндов не имеет. Записывает регистры в стек. Запись идет в следующих регистрах: AX, BX, CX, DX, SP, BP, SI, DI. Значения регистра SP повышается на 8. Данная команда автоматически добавляется в качестве 1-ой к коду, написанного на языке встроенного ассемблера.

PUSHAD – запись в стек 32-х разрядных регистров. Во встроенном ассемблере нет. Значение регистра SP увеличивается на 32.

POPA – восстановить содержимое регистров из стека. Обратная команде PUSHA. 32-х разрядная команда – POPAD.

XCHG – имеет два операнда. Осуществляет взаимный обмен информацией двух операндов.

 

7.6.2. Команды преобразования форматов.

 

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

 

Команды ввода вывода

 

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

 

Адресные команды

 

LEA – имеет два операнда. Вычисляет адрес шестнадцатиразрядного второго операнда и заносит его в первый операнд. Адрес вычисляется как относительный внутри модуля.

LDS – имеет два операнда. Вычисляет абсолютный адрес операнда 2. При этом сегмент адреса после выполнения команды находится в регистре DS, а смещение адреса – в операнде 1. В командах вычисления адреса употребляется не абсолютные переменные, а их адреса. Если мы пишем подпрограмму на языке встроенного ассемблера и вычисляем адрес передаваемого параметра, то в этом случае префиксы вычисления адреса употреблять не следует.

Procedure M1 (var M:String); assembler ;

…..

ASM

….

LDS BX, M

…..

END;

LES – аналогична команде LDS, но сегмент адреса загружается в регистр ES.

LFS – аналогично предыдущим двум. Сегмент адреса загружается в регистр FS.

LGS – сегмент адреса загружается в регистр GS.

LSS – сегмент адреса загружается в регистр SS.

Пример.

Напишем процедуру установки пиксела, аналогичную примеру 2 пункта 5.5. Используем встроенный ассемблер и непосредственное обращение к видеопамяти. Пиксел устанавливаем для видеорежима 320х200 точек на 256 цветов.

Procedure my_pixel(x,y : word; Color : byte);

Begin

ASM

PUSH ES

MOV AX,0A000h

MOV ES,AX

MOV AL,Color

MOV [ES:Y*320+X],AL

POP ES

END;

END;

 

 

7.6.5. Команды работы с регистром флагов.

 

LAHF – команда без операндов. Загружается в регистр AH.

SAHF – команда обратная предыдущей. Из регистра AH загружаются соответствующие биты в регистр флагов.

PUSHF – сохраняет флаг регистр в стек. Регистр SP повышается на 1.

PUSHFD – сохранение 32-бит. Флагового регистра. SP увеличивается на 2.

POPF – восстановление флагового регистра из стека.

POPFD – 32-разрядный.

Другие команды смотрите по литературе/2,3/.

 

       7.6.6. Арифметические команды

 

Длина операндов должна быть одинаковой. После выполнения команд могут быть установлены флаги: F, S, OF, SF, ZF, AF, PF, SF.

ADD – имеет два операнда. Прибавляет операнд 2 к операнду 1 и результат записывает в 1.

 Пример: ADD BL, AL

INC – имеет один операнд. Увеличивает значение операнда на 1.

DEC – уменьшить на 1.

SUB - Вычитает операнд 2 из операнда 1 и результат записывает в 1.

CMP – сравнить два операнда. Аналогично команде SUB , но результат не записывается в первый операнд.

Другие команды данного раздела на самостоятельное изучение.

 

Строковые команды

 

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

 

7.6.8. Логические команды.

 

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

Логическое умножение.

AND  Имеет 2 операнда. После выполнения команды изменяется содержимое флагов FS, FZ, FP.

Отрицание.

NOT Имеет 1 операнд. Необходимо помнить, что отрицание не эквивалентно смене знака.

Логическое сложение.

OR После выполнения команды изменяются флаги аналогично команде AND.

Исключающее «или»

XOR Аналогично предыдущим командам меняются флаги.

Логические команды работают быстрее пересылки, поэтому XOR AL, AL быстрее, чем MOV AL,0.

Произвести сравнение двух чисел

JE, JZ

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

Пример:

CМP AX, BX

JZ @M1

Проверяем значения AX и BX путем вычитания из AX BX без сохранения результата. Если операнды совпадали, то осуществляем переход на метку М1.

JNE , JNZ

Переход по неравенству, если флаг ZF не равен нулю.

JC , JB , JNAE

 Переход , если флаг CF = 1

JAE , JNC , JNE

Переход, если CF=0

JS

Переход, если старший разряд установлен в единицу (число отрицательное)

JNS

Переход, если флаг SF = 0 (положительное число).

Другие команды данного раздела изучаем самостоятельно.

 

7.6.11. Команды безусловного перехода.

 

CALL – вызвать программу. Один параметр – имя подпрограммы. При вызове подпрограммы она может быть вызвана как по длинному адресу, так и по короткому. Вызов определяется объявлением подпрограммы. При ближнем вызове содержимое регистра SP уменьшается на содержимое регистра IP. Регистр IP запоминается в стеке. В регистр IP загружается адрес подпрограммы. При дальнем вызове в сегмент также запоминается регистр SP и в регистры SP и IP вносится новый адрес программы.

RET – возврат из подпрограммы. Параметров нет. Осуществляет действие, обратные команде CALL.

JMP – безусловный переход на метку. Один параметр – метка. Метка в программе записывается специальным образом: <имя метки>. При этом метка может быть как 1 в строке, так и перед командой ASM. Для успешной трансляции Assembler кода рекомендуется не ставить метку в пустой строке, в крайнем случае, писать команду NOP.

 

7.6.12. Команды циклов.

 

LOOP – Организовать цикл. Имеет один параметр – метка, на которую передается управление начала цикла (аналогично REPEAT – UNTIL с фиксированным количеством повторений), перед началом цикла в регистр CX должна быть занесена информация о количестве повторений. При каждом обращении к команде LOOP регистр CX уменьшается на один. Выход из цикла – когда CX =0.

Пример. Перенесем 10 байтный массив в 5 байтный массив из слов.

type

tm=array[1..10] of byte;

ts=array[1..5] of word;

var

 m:tm;

 s:ts;

 pm,ps:pointer;

 i:integer;

begin

for i:=1 to 10 do m[i]:=100-10*(i-1);

for i:=1 to 5 do s[i]:=0;

writeln;

for i:=1 to 5 do write(s[i]:6);

writeln;

pm:=@m;

ps:=@s;

ASM

PUSH ES

PUSH DS

LES DI, PM

LDS SI, PS

MOV CX,5

@CIK:

 MOV AL,[ES:DI]

 INC DI

 MOV AH,[ES:DI]

 MOV [DS:SI],AX

 ADD SI,2

 LOOP @CIK

POP DS

POP ES

END;

for i:=1 to 5 do write(s[i]:6);

writeln;

READLN;

END.

Другие команды данного раздела изучаем самостоятельно.

 

7.6.13. Команды обработки прерываний.

 

INT – вызвать прерывание. Один параметр - номер прерывания в виде константы. В процессе выполнения прерывания в стек заполняются регистры: ВS, IP, FLAGS. Перед выполнением прерывания анализируется флаг прерывания. Он должен быть равен 1. После выполнения команды флаг прерываний имеет значение 0, т.е. другие прерывания в данный момент запрещены. Флаг TF также имеет значение 0, т.е. запрещен пошаговый отладочный режим.

INTO – выполнить 4-ое прерывание (прерывания переполнения).

IRET , IRETD – возвратиться из прерывания. Употребляется только в программе обработчика прерывания – команда, обратная INT. Возвращает управление на команду, следующую за командой INT или INTO.

CLI – сбросить флаг прерывания. Параметров нет. Как правило, употребляется в программе-обработчике прерываний и запрещает обработку прерываний, кроме общих системных.

STI – разрешить обработку всех отложенных прерываний. Установить флаг прерывания в 1. Как правило, программа-обработчик прерывания начинается командой CLI, а заканчивается STI и IRET.

Пример.

Напишем процедуру установки пиксела, аналогичную примеру 2 пункта 5.5. Используем встроенный ассемблер и прерывание 10h. Пиксел устанавливаем для видеорежима 320х200 точек на 256 цветов.

Procedure my_pixel(x,y : word; Color : byte);

Begin

ASM

MOV AH,0Ch

MOV CX,X

MOV DX,Y

MOV AL,Color

INT 10h

END;

END;

 

7.6.14. Команды поддержки языков высокого уровня

 

Предназначены для защищённого режима и привилегий (не входят в встроенный ассемблер).

 

7.6.15. Разные команды.

 

NOP – нет операции. Команда позволяет выровнять программу на границу слова. Если длинна вашей программы на языке ASM не кратна слову, то в процессе выполнения программы могут происходить сбои. Операндов нет.

WAIT – ждать окончания работы мат. сопроцессора.

ESC – выполнить команду (передать данные мат. сопроцессору). Имеет 2 операнда:

1-ый – 6-битовая константа, определяющая команду мат. сопроцессора, 2-ой – данные, передаваемые мат. сопроцессору.

LOCK – запретить работу мат. сопроцессора. Операндов не имеет. Прерывает работу сопроцессора и передает управление следующей за ней команде.

BSWAP – переставить байты в обратном порядке. Имеет один операнд – dword.

 

7.7. Дополнительные атрибуты у подпрограмм на Turbo Pascal.

 

Описание пpоцедуpы или функции полностью состоящей из утверждений ассемблера должно содержать объявление "assembler". Компилятор не использует переменную результата функции, и ссылка на символ @Result является ошибкой для всех типов данных, кроме стpок. Компилятор автоматически генеpиpует коды входа и выхода из ассемблерных пpоцедуp. Функции, использующие директиву «assembler», должны возвращать результат в следующем виде: 8-битные данные - в pегистpе AL, 16-битные - в pегистpе АХ; 32-битные целые и указатели - в pегистpах DX и AX; 6-байтное действительное число - в pегистpах DX,BX и АХ; другие вещественные и целые числа в pегистpе стека ST(0) сопpоцессоpа 8087 /4/.

Реализуем пример программы из пункта 7.6.12 в виде процедуры реализованной на языке встроенного ассемблера.

type

tm=array[1..10] of byte;

ts=array[1..5] of word;

 

procedure conv(var s:ts; m:tm);assembler;

ASM

PUSH ES

PUSH DS

LES DI,[M]

LDS SI,[S]

MOV CX,5

@CIK:

 MOV AL,[ES:DI]

 INC DI

 MOV AH,[ES:DI]

 MOV [DS:SI],AX

 ADD SI,2

 LOOP @CIK

POP DS

POP ES

END;

 

var

 m:tm;

 s:ts;

 i:integer;

begin

for i:=1 to 10 do m[i]:=100-10*(i-1);

for i:=1 to 5 do s[i]:=0;

writeln;

for i:=1 to 5 do write(s[i]:6);

writeln;

conv(s,m);

for i:=1 to 5 do write(s[i]:6);

writeln;

READLN;

END.

 

В TURBO PASCAL возможно использование подпрограмм, написанных на других языках программирования или хранящих внутри себя файловые ресурсы. Существует единственное ограничение – длина 1 подпрограммы, хранящей ресурс или написанной на другом языке программирования, не должна превышать 1 стр. Существует 2 атрибута, определяющих тип подпрограммы. Это атрибут подпрограмма или ресурс, оттранслированные в другом языке программирования, и атрибут Assembler – подпрограмма, написанная на встроенном языке ASM’а. В программу на ТР можно вставить подпрограмму, написанную на языка С++ или Turbo Assembler. В этом случае подпрограмма в данном языке должна иметь атрибут Pascal . Программа должна быть оттранслирована в объектный код, т.е. до трансляции на языке Pascal в текущие директории должны храниться с расширением * OBJ.

 Пример: включения функции MYFUN, возвращающей целое значение, по написанной на C++ или на Assembler.

 FUNCTION MY FUN: Integer; External;

{$L My Fun. OBJ}

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

Пример: BINOBJ MYDAT DAT MYDAT Proc Dat.

В результате выполнения этой утилиты текущей директории будет создан файл MYDAT.OBJ

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

Пример: P.dat: =@Proc Dat;

 

ЯЗЫК ПРОГРАММИРОВАНИЯ С.

 

8.1. Константы.

В языке С существует три вида арифметических констант.

десятичные (обязательно начинаются с цифры от 0 до 9)

восьмеричные (начинаются с цифры 0 и включают цифры от 0 до 7)

шестнадцатеричные (начинаются с 0х или 0Х и могут включать в себя цифры от 0 до 9 и символы от A до F

Кроме того, программист может задать длину константы. Если за числом не идет никакого символа, то константа является короткой, если же за числом есть символ l(L), тогда константа длинная.

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

Примеры:

100     - десятичное сто

0100     - восьмеричное

0х100   - шестнадцатеричное

100L     - десятичное длинное (4 байта)

0100L   - восьмеричное длинное

0х100L - шестнадцатеричное длинное

 

Вопрос: Как записать десятичное число 0,9 в восьмеричной форме? Ответ: 011Е-1.

В языке С различаются символьные и строковые константы. Символьная константа состоит из одного символа и заключается в апострофы (к примеру, можно записать так - ‘а’). Строковая константа состоит из нуля или более символов и заключается в двойные апострофы (например, “ас”). В конце строки обязательно ставится символ с кодом 0 (все строки в языке С типа PChar). Кроме того символ может быть задан специальной последовательностью, при этом такая последовательность обязательно начинается обратным знаком деления («\») и заключается в апострофы или двойные кавычки.

Предопределенные знаки:

\n – новая строка, перевод строки

\t – табуляция

\v – вертикальная табуляция

\b – возврат на шаг

\r – возврат каретки

\f – перевод формата

\\ - \ 

\’’ – '

\”” – “

\0 – код нуля

\<nnn> - , где nnn задает код символа от 0 до 255.

Для унификации программного обеспечения рекомендуется употреблять в строках только следующие обозначения: \n, \t, \r, \f, \\, \’ ,\”, \0.

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

 

8.2. Синтаксис С.

 

Тип строка записывается следующим образом Char[]. Символы [ и ] говорят о том, что пользователь задает массив. Нижняя граница массива всегда равна нулю. Верхняя граница может быть как заданной, так и незаданной. Если граница задана, то транслятор выделяет память под данные в начале работы программы. Если граница не задана, то массив будет распределен динамически в куче. При этом правильность выделения массива лежит полностью на программисте.

Комментарии начинаются на /* и заканчиваются на */.

 

Программа на языке С состоит из трех частей:

включаемые модули и директивы компилятора

определение типов и переменных внутри программы

программный код

 

8.3. Типы памяти переменных

 

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

auto (в соответствии с вышеперечисленными правилами, приписывается по умолчанию)

Extern (внешняя переменная, распространяет свою область на весь программный комплекс)

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

Static (тип переменных, которые уничтожаются после завершения работы функции или операторных скобок).

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

 

8.4 Структуры в С.

 

Структура языка С имеет ключевое слово struct <имя> { здесь перечисляются поля}

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

Union <name> {перечисляемые поля}

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

В отличии от Паскаля в С можно определить как поле в записи только несколько бит из байта. Слова или двойного слова. Это делается с помощью разделителя «:» и числа, стоящим за ним.

Пример.

struct my {

              unsigned int bi10:10;

              unsigned int bi6:6;

              unsigned char a;

              char b;

              long int c

           }

В данной структуре my определены два поля bi10 и bi6, которые объединяются в одно слово.

 

8.5. Операции в выражениях.

 

8.5.1. Арифметические операции.

“+” – сумма, может быть определена между числами и указателями

“-” – аналогично

“*” – аналогично в языке Паскаль (только между числами)

“/” – аналогично в языке Паскаль, но результат деления определяется типами участвующих чисел по следующему правилу: если один из целых операндов длиннее другого, то короткий операнд преобразуется к более длинному. Если один из операндов – действительное число, то второй операнд преобразуется к действительному. Если одно из действительных чисел длиннее второго, то второе преобразуется к более длинному. В некоторых трансляторах иногда происходит ошибка, поэтому рекомендуется при сложных вычислениях задавать порядок преобразований непосредственно программисту. Порядок преобразования задается утверждением (<тип>) <данное>, например (real)I.

“%” – остаток от деления на цело (соответствует Mod в Паскале)

“++” – увеличивает значение выражения на 1, но возвращает результат равный предыдущему, например, {j=4; I=++j;} в результате I=4, j=5.

“<выр>++” – аналогично, только результат возвращается равный значению переменной, например, { j=4; I=++j;} в результате I=5, j=5.

“<выр>--” – аналогично “<выр>++”

“--<выр>” – аналогично “++<выр>”. Операции ++ и – могут быть проделаны как над числами, так и над указателями.

Операция присваивания =, например, I=4

Присваивание с модификацией переменной “+=”, например, {I=5;j+=7}, в результате I=12

“+=” – аналогично предыдущей. Данные операции могут производиться как над переменными числовых типов, так и над указателями.

“*=” - только над числовым типом, например, {I=2;j=3;I*=j++}, в результате I=8.

“/=” – аналогично предыдущему.

“%=” – аналогично

“>>=” – сдвиг вправо, например, {I=4;I>>=1;}, в результате I=2.

 “<<=” – сдвиг влево

“&=” - логическое умножение, пример, {I=12;j=4;I&=J}, в результате I=4.

“!=” – логическое сложение, например, {I=12;j=4;I!=J}, в результате I=12.

“^=” - исключающее или

Пример, {I=12;j=4;I^=J}.

 

8.5.2. Адресные операции.

& - вычисляет адрес переменной (в Паскале @). Пример, I=&N.

* - присваивание значения указателю. Пример, {N=5;I=&N;*I=10;}.

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

 

8.5.3. Операции отношения.

Операции отношения употребляются в логических операторах и операторах цикла.

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

!= - проверка на неравенство, допускается как арифметический тип, так и строковый, а также указатели.

< - операция меньше, допускается все типы данных, а также указатели.

<= - операция меньше или равно, допускается все типы данных, а также указатели.

> - операция больше, допускается все типы данных, а также указатели.

>= - операция больше или равно, допускается все типы данных, а также указатели.

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

! – отрицание.

!! – логическое сложение.

&& - логическое умножение.

 

8.5.4. Специальные операции.

Встроенная логическая операция:

синтаксис: (<лог. выр.>?< выр.1>:< выр.2>)

<лог. выр.> - выражение, которое проверяется до выполнения < выр.1> или < выр.2>.

< выр.1> - выполняется, если логическое выражение истинно.

< выр.2> - выполняется, если логическое выражение ложно.

           

       Пример : C=((A<0) ? A/2 : SQRT(A));

Определить размер:

синтаксис: SIZE of (<тип/массив>)

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

(<тип>) – функция явного преобразования.

Пример : в Turbo Pascal Word(I), Real(K) в Си (Word)I, (Real)K соответственно.

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

 

В основу TURBO PASCAL положен принцип получения правильно работающей программы за минимальное время, он заключается в четких проверках типов и длин данных и минимального использования преобразования между переменным. для С положен принцип минимального времени получения программы. В отличие от TURBO PASCAL не производится четких проверок между типами переменных и более развита работа с указателями. Кроме того, в Си в одном операторе можно может производиться массовая обработка данных в отличие от языка Turbo Pascal.

Си : I++, J=0, k=--4; - один оператор.

 

8.6. Операторы языка Си.

 

Оператор { } (в Turbo Pascal “ Begin End ;”)

Логический

If (<ЛВ>) <ОП true > [ else <ОП false >]

Пример:    If (A<3)

                               If (A<5)

                               Else B=2;

Else относится ко второму If.

Сложный логический оператор:

Switch (<B ыр. >){

Case <const>:<O П 1 >  ;…; < ОП N >;

Else <const> < ОП >1

…………………………………

Case <constK>:<O П 1 >;…; < ОП N >;

[default : <O П 1 >  ;…; < ОП N >;]}

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

Пример : Turbo Pascal:

Case of

1 : A:=1

2 : A:=2

end;

 

Си:

Switch {

Case 1 : A=1

Case 2 : A=2

}

Если I=1, то case в Turbo Pascal присваивает переменной 1, в Си Switch присваивает переменной A – значение 2.

Для того чтобы выйти из любого цикла существует оператор Break.

В Си есть оператор продолжить цикл Continue (т.е. тело цикла игнорируется).

Оператор с фиксированным значением повторений:

For (< B 1 >[;< B 2 >;[< B 3 >]]) <ОП>;

B1 – начальные параметры цикла.

В2 – выражение истинность которого выполняется для продолжения цикла

В3  - постоянная часть цикла.

Пример: в Turbo Pascal:

For I:=0 to 9 do M[I]:=0;

В Си:

For (I=0; I<10; I++) M[I]=0;

Так как в Си может состоять из нескольких выражений то одним оператором цикла for можно описать сразу несколько циклов.

For (i=0; j=N-1; i<N; I++, j--) a[i]=a[j];

 

Оператор Do While

DO <ОП> While (<ЛВ>) – повтор один или несколько раз.

(в Turbo Pascal: repeat - until)

While

While (<ЛВ>) <ОП>;

(в Turbo Pascal: While)

 

8.7. Функции в языке Си.

 

В языке Си употребляются только функции, при этом функция может возвращать, а может не возвращать значение, если функция не возвращает значение то вместо типа возвращаемого значения записывается ключевое слово VOID, в отличии от Turbo Pascal, количество посылаемых в функцию параметров может не соответствовать параметрам, определенным для функции, обмен информации происходит по следующему алгоритму, в стек записываются все переменные и Const пересылаемые в функцию, вызывается функция и из стека последовательно считываются данные соответствующие типам аргумента функции, при этом проверка правильности типов не осуществляется.

Описание функции:

<TB>

<имя Ф>[(<П1>,<П2>,…,<ПN>)]

<Тип1><n1>;

<Тип2><n2>;

…………….

<ТипN><nN>;

{

/*Tело Ф*/

[Return(<B>);]

}

<TB> - тип возврата

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

Double

LimFunc(x,a,b)

Double : x

Double : a

Int registers b;

{Return (a*b+x)

}

 

Пример обращения:

Правильный: L= LimFunc(2e-1,3e-2,14)

Не правильный: L= LimFunc(2e-1,5,14)

 

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

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

 

8.8. Структура головной программы на языке Си

 

main (arqc, arqv, envp)

int arqv

char ** arqv

char ** enpv

{

/*меню программы/

}

 

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

В TP соответствует ParamCount

arqv – массив параметров, передающий в программу символьная матрица неопределенной длины.

enpv – символьная матрица, передающая в себя установки в ОС. Данная матрица не заполняется, а формируется транслятором автоматически.

 

8.9. Включаемые библиотеки

 

В языке Си существует множество директив к транслятору, позволяющих создавать независимые от платформы программное обеспечение. Директивы к транслятору начинаются со знака #. Наиболее часто употребляются директивы #include </”<ф>”/> - включить файл. Включение текстов программ. Файл имеет расширение *.h (в языке Си *.c или *.cpp). Если имя файла идет в знаках < >, например, #include <math.h>, то файл math.h ищется в стандартной директории языка Си. Если имя файла заключено в “”, то файл ищется по директориям:

текущей директории;

директории определяемой ОС, с атрибутом path;

стандартной директории языка Си.

 

“!” с помощью первой записи описываются стандартные библиотеки, с помощью второго - пользовательские.

 

Кроме include существуют:

#define

#undef

#if<ЛВ>

#ifdef<ЛВ>

#else

#endif

#line

 

Стандартные библиотеки

 

Stdio.h – библиотека ввода/вывода. Определяет понятие файла, операции с файлами, вывод и ввод информации в соответствии с правилами ввода/вывода текстовых файлов, форматирование вывода информации в строку или файл. В стандартном языке Си существует * обработка файлов, которая соответствует обработке файлов, с атрибутом file в Паскале. В настоящее время лишние функции ввода/вывода в некоторых трансляторах отсутствуют; в языке Паскаль используемые библиотеки являются независимыми, а в языке Си существуют несколько направлений библиотек. Библиотека ввода/вывода, математики, обработки строк и т.д. При этом чтобы использовать более развитую библиотеку необходимо в тексте программы описать более простые, в соответствии данному направлению.

 

 Библиотека проверки строк ctype.h. Осуществляет проверку символов, находящихся в строке и различные преобразования над ними. Занимается распределением кучи.

 

Math.h осуществляет арифметические функции над действительными и целыми числами.

 

“!” Описание библиотек идет перед описанием переменных. Правила использования библиотек в СИ соответствуют правилам использования библиотек в языке Паскаль.

 

ЛИТЕРАТУРА

1. Ложкин А.Г. Компьютерная графика. Конспект лекций по курсу «Компьютерная графика» для специальностей 220200, 220300, 552800, Ижевск, 2003.

2. Абель. П. Ассемблер. Язык и программирование для IBM PC, M.: Век, 2003 (5-е издание)

3. Юров В. И. Assembler. Учебник для вузов СПб.: Питер, 2003, 640 стр.

4. Ложкин А.Г. Программирование на смеси языков высокого уровня и Ассемблера. УМК 53/95. Метод. указ. для практ. и лаб. занятий по курсу “Системное программное обеспечение” для студ. спец. 220200, Ижевск, ИжГТУ, 1995(1 изд.), 2002 (2 изд.). 37 с.

 

 

ЭКЗАМЕНАЦИОННЫЕ ВОПРОСЫ

 

Назначение системного ПО

Обмен информации в компьютере (супервизор, поиск информации)

Обработка текстовых файлов

Обработка типизированных файлов

Обработка не типизированных файлов

Адресация памяти на платформе ЭВМ PC

Обращение к ОП на языке Паскаль(сегмент команд, данных, стек, куча)

Предопределенные массивы

Основные регистры процессора 80286 

Флаговый регистр

Библиотека DOS. работа с файлами

Обработка прерываний(прерывание, вектор прерываний и принципы переопределения векторов прерываний)

Библиотека DOS. Процедуры и функции, работающие с прерываниями ОС.

Понятие программного оверлея(Overlay, перекрестная ссылка)

Режимы адресации в Ассемблере(правила использования, использования Ассемблера в языке Паскаль общих для любого билета по встроенному Ассемблеру)

Выражения Ассемблера

Команды общего назначения(типы данных для языка Паскаль и Ассемблера)

Команды ввода/вывода и адресные команды

Команды работы с файлами

Арифметические команды(+, -)

Арифметические команды(*,/)

Команды перехода

Строковые команды

Логически команды

Команды циклов и битовые команды

Команды обработки прерываний

Специальные команды

Вставка двоичных файлов. Текст программы на Паскале

Описание (типов) count на языке Си

Типы памяти. Описание структуры языка Си

Арифметические выражения языка Си

Логические выражения и операции с адресами

Операции отношений и специальные операции

Логические операторы языка Си

Операции циклов языка Си (break, continue)

Использование файлов в языке Си

Структура головной программы и включение библиотек в языке Си

СТРУКТУРА ТЕХНИЧЕСКОГО ЗАДАНИЯ НА КУРСОВУЮ РАБОТУ

 

ЗАГОЛОВОК:

Техническое задание на курсовую работу

Название курса – СПО

На тему: название темы

 

1. Цель создания системы (программы)

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

-  Конкретное назначение программы;

    2-3. Преимущества разрабатываемого программного продукта по сравнению с существующими;

1. Конкретные особенности программы.

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

 

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

- Технические характеристики компьютера. Их необходимо писать в соответствии с общепринятыми обозначениями:

1. тип платформы;

2. процессор;

3. быстродействие процессора;

4. оперативная память;

5. объем винчестера;

6. тип видеопроцессора;

7. объем оперативной видеопамяти.

- – 2.3 Дополнительное периферийное оборудование;

2.4 Операционная система;

2.5 Язык программирования, на котором разрабатывался программный продукт.

3. Задачи, реализуемые в ходе курсового проекта:

3.1 Перечень задач, решаемых подсистемой (больше чем в п.1);

3.2 Технические средства, на которых разработана подсистема;

3.3 Языки программирования, используемые в курсовом проекте;

3.4 Общие требования к программе. В курсовом проекте должны быть использованы системные средства и конкретные требования, предъявляемые научным руководителем;

· Состав отчета (состав пояснительной записки).

Состав пояснительной записки:

 

Пояснительная записка должна содержать следующие пункты:

· Введение (обосновать необходимость СПО);

· Обзор существующих языков программирования (не менее 3-х языков), обязательные ссылки на литературу. После обзора необходимо обосновать выбор языка с точки зрения системного программирования;

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

· Описание алгоритма программы обязательно с блок-схемой. Блок-схема не должна быть выделена в отдельную подглаву. Описание блок-схемы обязательно.

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

· Список литературы. Указать не менее трех источников по языкам программирования и 1-2 источника по математической модели. Ссылки только на имена сайтов недопустимы, ссылки на имена электронных документов на сайте возможны;

· Приложения.

1. Текст программы;

2. Результаты работы программы;

 

 

 

ВВЕДЕНИЕ В СИСТЕМНОЕ ПРОГРАММИРОВАНИЕ

 

 

Конспект лекций

для студентов специальности 220200, 552800 по курсу «Системное программное обеспечение», 220300 по курсу «Лингвистическое и программное обеспечение»

 

 

 

 

 

Ижевск, 2003



АННОТАЦИЯ

Конспект лекций в сжатом виде дает важнейшие темы по курсу «Системное программное обеспечение»: процессы обмена информации и доступа к оперативной памяти; системная библиотека языка ПАСКАЛЬ; методы получения выполняемой программы; программирование на языке АССЕМБЛЕР; программирование на языке С.



СОДЕРЖАНИЕ


Поделиться:



Последнее изменение этой страницы: 2019-04-19; Просмотров: 214; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (1.139 с.)
Главная | Случайная страница | Обратная связь