- •Часть I. Работа в среде
- •Глава 1. Интегрированная среда
- •1.1. Окно просмотра результатов Output
- •1.2. Окно просмотра переменных Watch
- •1.3. Структура меню
- •1.3.1. Пункт File (работа с файлами)
- •1.3.2. Пункт Edit (работа с редактором)
- •1.3.3. Пункт Run (запуск на выполнение)
- •1.3.4. Пункт Compile (компиляция)
- •1.3.5. Пункт Options (установка параметров системы)
- •1.3.6. Пункт Debug (установки отладчика)
- •1.3.7. Пункт Break/Watch (точки останова/обзор)
- •1.4. Интерактивная справка
- •Глава 2. Настройка системы
- •2.1. Система настройки среды программирования
- •2.2. Принятые в системе расширения имен файлов
- •Часть II. Язык турбо паскаль
- •Глава 3. Построение программ
- •3.1. Алфавит языка и зарезервированные слова
- •3.2. Общая структура программ
- •3.3. Комментарии и ключи компиляции
- •3.4. Условная компиляция программ
- •Глава 4. Введение в систему типов языка
- •4.1. Простые типы языка
- •4.1.1. Целочисленные типы
- •4.1.2. Вещественные числа
- •4.1.3. Логический тип
- •4.1.4. Символьный тип
- •4.1.5. Строковый тип
- •4.1.6. Адресный тип
- •4.1.7. Перечислимые типы
- •4.1.8. Ограниченные типы (диапазоны)
- •4.2. Сложные типы языка
- •Глава 5. Константы и переменные
- •5.1. Простые константы
- •5.2. Переменные
- •5.2.1. Совмещение адресов директивой absolute
- •5.2.2. Переменные со стартовым значением или типизированные константы
- •5.3. Операция присваивания и совместимость типов и значений
- •5.4.Изменение (приведение) типов и значений
- •Глава 6. Управляющие структуры языка
- •6.1. Простой и составной операторы
- •6.2. Условный оператор (if...Then...Else)
- •If Условие then Оператор1 else Оператор2;
- •6.3. Оператор варианта (case)
- •6.4. Оператор цикла с предусловием (while)
- •6.6. Оператор цикла с параметром (for...Do)
- •6.7. Оператор безусловного перехода Goto
- •6.8. Операторы Exit и Halt
- •6.9. Процедуры и функции
- •6.9.1. Параметры. Глобальные и локальные описания
- •6.9.2. Опережающее описание процедур и функций
- •6.9.3. Объявление внешних процедур
- •6.9.4. Процедуры и функции как параметры
- •6.9.5. Переменные-процедуры и функции
- •6.9.6. Специальные приемы программирования
- •6.10. Модули. Структура модулей
- •6.11. Особенности работы с модулями
- •6.12. Система библиотечных модулей языка
- •Часть III. Средства языка турбо паскаль
- •Глава 7. Массивы, записи и множества в деталях
- •7.1. Массивы (Array) и работа с ними
- •7.2. Тип «запись» (Record) и оператор присоединения With
- •7.3. Тип «множество» (Set). Операции с множествами
- •Глава 8. Обработка символов и строк
- •8.1. Символьный и строковый типы (Char и String)
- •8.2. Операции над символами
- •8.3. Операции над строками
- •8.3.1. Редактирование строк
- •8.3.2. Преобразование строк
- •8.3.2.1. Процедура Str( X [: Width [: dec ] ]; var s : String)
- •Глава 9. Математические возможности Турбо Паскаля
- •9.1. Базовые операции
- •9.2. Битовая арифметика
- •9.3. Логические вычисления и операции отношения
- •9.4. Математические процедуры и функции
- •9.4.1. Обсуждение математических функций языка
- •9.4.2. Генераторы случайных чисел
- •9.4.3. Оптимизация сложения и вычитания
- •9.5. Использование математического сопроцессора 80x87
- •Глава 10. Код программы, данные, адреса
- •10.2. Распределение памяти при выполнении программ
- •10.3. Анализ расположения кода и областей данных программы
- •10.5. Средства для работы с адресами
- •10.5.1. Определение адреса переменных
- •10.5.2. Создание адреса функцией Ptr
- •10.5.3. Определение размеров типов и переменных
- •Глава 11. Ссылки, динамические переменные и структуры
- •11.1. Ссылочные переменные
- •11.2. Операция разыменования
- •11.3. Организация памяти области кучи
- •11.4. Управление размерами области кучи и стека
- •11.5. Процедуры управления кучей
- •11.5.1. Размещение динамических переменных.
- •11.5.2. Освобождение динамических переменных.
- •11.5.3. Управление состоянием кучи.
- •11.5.4. Анализ состояния кучи.
- •11.5.5. Более детальный анализ состояния кучи
- •11.6. Ссылки, работающие не с кучей
- •11.5.6. Обработка ошибок распределения памяти
- •11.7. Как организовать структуры, большие чем 64к?
- •11.8. Практический пример построения стека
- •Глава 12. Ввод-вывод данных и файловая система
- •12.1. Понятие логического файла
- •12.2. Физические файлы в ms-dos
- •12.3. Понятие буфера ввода-вывода
- •12.4. Файловые типы Турбо Паскаля
- •12.5. Общие процедуры для работы с файлами
- •12.5.1. Связывание файлов
- •12.5.2. Открытие файлов
- •12.5.3. Закрытие файлов
- •12.5.4. Переименование файлов
- •12.5.5. Удаление файлов
- •12.5.6. Анализ состояния файлов
- •12.6. Текстовые файлы
- •12.6.1. Текст-ориентированные процедуры и функции
- •12.6.2. Операции ввода-вывода в текстовые файлы
- •123 1.23 [Клавиша ввода]
- •123 [Клавиша ввода] 1.23 [Клавиша ввода]
- •12.7. Типизированные файлы и операции ввода-вывода
- •12.8. Бестиповые файлы и операции ввода-вывода
- •12.9. Последовательный и прямой доступ к файлам
- •12.9.1. Опрос размеров файлов и позиции в них
- •12.9.2. Позиционирование в файлах
- •12.9.3. Усечение файлов
- •12.10. Процедуры для работы с каталогами
- •12.11. Обработка ошибок ввода-вывода
- •12.11.1. Функция ioResult
- •12.11.2. Примеры обработки ошибок ввода-вывода
- •12.11.3. Сводка номеров ошибок ввода-вывода
- •Глава 13. Объектно-ориентированное программирование
- •13.1. Определения объектов
- •13.2. Область действия полей объекта и параметр Self
- •13.3. Наследование
- •13.4. Присваивание объектов
- •13.5. Полиморфизм
- •13.5.1. Статические методы
- •13.5.2. Виртуальные методы
- •13.5.3. Выбор вида метода
- •13.6. Динамические объекты
- •13.6.1. Создание динамических объектов
- •13.6.2. Освобождение объектов. Деструкторы
- •13.6.3. Обработка ошибок при работе с динамическими объектами
- •13.7. Функции TypeOf и SizeOf
- •13.8. Задание стартовых значений объектам
- •13.9. Модули, экспортирующие объекты
- •Глава 14. Специальные средства языка
- •14.1. Работа с командной строкой. Функции ParamCount и ParamStr
- •14.2. Доступ к памяти пэвм. Массивы Mem, MemW, MemL
- •14.3. Доступ к портам ввода-вывода. Массивы Port и PortW
- •14.4. Процедура заполнения FillChar
- •14.5. Процедура перемещения данных Move
- •14.6. Функции обработки машинных слов Lo, Hi и Swap
- •14.7. Вставки машинного кода в программе
- •14.7.1. Оператор inline
- •14.7.2. Процедуры с директивой inline
- •14.8. Процедура завершения и обработка ошибок программ
- •14.8.1. Оператор RunError
- •14.8.2. Сводка номеров фатальных ошибок
- •Часть IV. Специальные библиотеки языка
- •Глава 15. Модуль crt
- •15.1. Вывод специальных символов
- •15.2. Модификация операторов Read, ReadLn
- •15.3. Системные переменные модуля crt
- •15.3.1. Переменные управления выводом на дисплей
- •15.3.2. Переменные управления работой клавиатуры
- •15.3.3. Переменная TextAttr
- •15.4. Процедуры и функции модуля crt
- •15.4.1. Работа с экраном в целом
- •15.4.2. Позиционирование курсора
- •15.4.3. Работа со строками
- •15.4.4. Настройка цвета
- •15.4.5. Подача звуковых сигналов
- •15.4.6. Использование встроенного таймера
- •15.4.7. Опрос клавиатуры
- •If KeyPressed then Действие ;
- •15.4.8. Переназначение стандартных файлов
- •Глава 16. Модуль dos
- •16.1. Опрос и установка параметров ms-dos
- •16.1.1. Управление параметрами break и verify 16.1.1.1.
- •16.1.2. Опрос системных переменных ms-dos
- •16.2. Работа с часами и календарем
- •16.2.1. Опрос и назначение даты
- •16.2.3. Работа с датой создания файлов
- •16.3. Анализ ресурсов дисков
- •16.4. Работа с каталогами и файлами
- •16.4.1. Типы и константы модуля dos для работы с файлами
- •16.4.2. Переменная DosError
- •16.4.3. Процедуры поиска файлов на диске
- •16.4.4. Работа с атрибутами файлов
- •16.4.5. Анализ имен файлов
- •16.5. Работа с прерываниями ms-dos
- •16.5.1. Чтение и перестановка адресов подпрограмм прерываний
- •16.5.2. Вызов прерывания процедурой Intr
- •16.5.3. Процедура MsDos
- •6.6. Организация субпроцессов и резидентных программ
- •16.6.1. Программирование субпроцессов
- •Глава 17. Модуль Printer
- •7.1. Содержимое модуля Printer
- •17.2. Низкоуровневые средства работы с принтером
- •17.3. Работа с двумя принтерами одновременно
- •Глава 18. Модуль Overlay
- •18.1. Оверлейное построение программ
- •18.2. Правила оформления оверлейных программ
- •18.3. Инициализация работы оверлеев
- •18.3.1. Включение администратора оверлеев
- •18.3.2. Анализ результата инициализации
- •18.3.3. Размещение оверлейного файла в ems-памяти
- •18.4. Управление оверлейным буфером
- •18.4.1. Опрос размера буфера
- •18.4.2. Установка размера буфера
- •18.4.3. Принудительная очистка буфера
- •18.5. Оптимизация работы оверлеев
- •18.5.1. Установка размера области испытаний
- •18.5.2. Подсчет вызовов оверлеев
- •18.6. Предопределенные переменные для работы с оверлеями
- •18.7. Включение оверлеев в ехе-файлы
- •Глава 19. Модуль Graph
- •19.1. Файлы bgi и содержимое модуля Graph
- •19.2. Управление графическими режимами
- •19.2.1. Инициализация и закрытие графического режима
- •19.2.2. Обработка ошибок инициализации
- •19.2.3. Классификация и анализ графических режимов
- •19.2.4. Очистка экрана и переключение режимов
- •19.2.5. Управление режимом вывода отрезков на экран
- •19.3. Системы координат и «текущий указатель»
- •19.3.1. Координаты устройства и мировые координаты
- •19.3.2. Управление «текущим указателем»
- •19.4. Рисование графических примитивов и фигур
- •19.4.1. Линии и их стили
- •1100110011001100 — Всего 16 разрядов.
- •19.4.2. Коэффициент сжатия изображения
- •19.4.3. Окружности, эллипсы и дуги
- •19.4.4. Построение прямоугольников и ломаных
- •19.5. Управление цветами и шаблонами заливки (заполнения)
- •19.5.1. Немного о цветах
- •19.5.2. Задание типа заливки
- •19.5.3. Заливка областей изображения
- •19.5.4. Опрос и установка цветов пера и фона
- •19.5.5. Управление палитрой
- •19.6. Битовые графические операции
- •19.6.1. Битовые операции
- •19.6.2. Работа с фрагментами изображений
- •19.7. Управление видеостраницами
- •19.8. Графические окна
- •19.9. Вывод текста
- •19.9.1. Выбор шрифта и стиля
- •19.9.2. Предварительная загрузка и регистрация шрифтов
- •19.9.3. Непосредственный вывод строк
- •19.9.4. Размер букв и его масштабирование
- •19.9.5. Опрос стиля и ориентации шрифтов
- •19.10. Включение шрифтов и драйверов в ехе-файл
- •19.11. Подключение новых драйверов
- •19.12. Один полезный совет
- •Часть V. Практические
- •Глава 20. Профессиональная работа с
- •20.1. Программный опрос режимов текстового дисплея
- •20.2. Организация доступа к видеопамяти
- •20.3. Запоминание окон экрана и их восстановление
- •20.3.1. Общие принципы работы с окном
- •20.3.2. Модуль Win
- •20.4. Работа с образом экрана на диске
- •20.5. Крупные надписи на экране
- •20.6. Управление формой курсора
- •Глава 21. Как осуществить полный доступ к клавиатуре
- •21.1. Как организовать опрос алфавитно-цифровой клавиатуры
- •21.2. Опрос клавиши в регистре Ctrl
- •21.3. Опрос расширенных кодов и функциональных клавиш
- •21.4. Опрос служебных клавиш
- •21.5. Анализ клавиш регистров и их состояния
- •21.6. Скэн-коды клавиатуры и работа с ними
- •21.7. Эффект обратной записи в буфер ввода
- •Глава 22. Работа с оперативной
- •22.1. Многобитовое и многоплоскостное озув
- •22.2. Карта дисплейной памяти
- •22.3. Вывод текста на графический экран
- •22.4. Работа с графическими образами на диске
- •Приложение 2 Ключи и директивы компилятора
- •Ключи режимов компиляции
- •Директивы с параметрами
- •Приложение 3
- •Файл tpc.Cfg
- •Приложение 4 Список утилит пакета Турбо Паскаль (версия 5.5)
- •Программа администрирования библиотек
- •Утилита поиска текстов grep
- •Утилита преобразования двоичных файлов binobj
- •Приложение 5
- •Основные команды перемещения курсора
- •Расширенный набор команд перемещения курсора
- •Команды вставки и удаления
- •Команды работы с блоками
- •Поиск и замена
- •Прочие команды
- •Приложение 6
- •If False then Оператор;
- •Приложение 7
- •Глава 6. Управляющие структуры языка
- •Глава 8. Обработка символов и строк
- •Глава 9. Математические возможности Турбо Паскаля
- •Глава 16. Модуль dos
- •Глава 17. Модуль Printer
- •Глава 18. Модуль Overlay
- •Глава 19. Модуль Graph
- •Глава 20. Профессиональная работа с текстовыми изображениями
- •Глава 21. Как осуществить полный доступ к клавиатуре
- •Глава 22. Работа с оперативной памятью видеоадаптеров
- •Литература
- •Оглавление
- •Часть I. Работа в среде программирования
- •Часть II. Язык турбо паскаль
- •Часть III. Средства языка турбо паскаль
- •Часть IV. Специальные библиотеки языка
- •Часть V. Практические приемы работы с пэвм
16.5.2. Вызов прерывания процедурой Intr
Процедура Intr( N : Byte; VAR R : Registers) выполняет прерывыниe номер N, передавая ему значения через регистры переменной R и в ней же возвращая состояние регистров после обработки прерывания.
Пример использования процедуры Intr дан на рис. 16.13.
16.5.3. Процедура MsDos
Процедура MsDos (VAR R: Registers) реализует частный случай вызова Intr( N, R ) для N = 33 (21Н). Эта процедура вызывает и выполняет одну из функций DOS прерывания с номером 21Н. Каждая функция имеет свой набор входных значений регистров в {373}
USES DOS; {Печать экрана на принтере, как при нажатии Shift+PrtScr} PROCEDURE PrintScreen; VAR R : Registers; BEGIN Intr( $05, R ) { вызов системного прерывания } END; BEGIN Write( 'Нажмите ENTER для запуска печати экрана ' ); ReadLn; PrintScreen; END. |
Рис. 16.13
записи R типа Registers. Обычно в R.AH должен содержаться номер функции, в R.AL и следующих — параметры для вызова. После выполнения процедуры MsDos регистр R.AL содержит, как правило, код завершения операции (0, если все в порядке) и возвращаемые величины в других регистрах. Пример использования MsDos — определение множества букв, обозначающих доступные в ПЭВМ диски (рис. 16.14). Для работы примера требуется MS-DOS версий 3.0 и старше.
USES DOS; { АНАЛИЗ НАЛИЧИЯ ДИСКОВОДОВ В ПЭВМ } TYPE DrivesSetType = Set of 'A'..'Z'; { множество букв } { Процедура возвращает множество букв дисков в ПЭВМ } PROCEDURE TestDrives( VAR Drives : DrivesSetType ); VAR R : Registers; { переменная-регистры } i : Byte; { параметр цикла } ch : Char; { буква очередного диска } BEGIN ch := Pred('A'); { символ перед 'A' } Drives := []; { стартовое значение набора } for i:=1 to 26 do begin { от диска A: до... } ch:=Succ( ch ); { буква рассматриваемого диска } R.AH := $44; { номер функции MS-DOS } R.AL := $08; { загрузка параметра в AL } |
Рис. 16.14 {374}
R.BL := i; { загрузка номера диска в BL } MsDos( R ); { вызов функции номер 44Н } if R.AX <= 1 { если АХ>1, то диска нет } then Drives := Drives + [ch] end {for} END; VAR { ПРИМЕР ВЫЗОВА } с : Char; { параметр цикла } HD : DrivesSetType; { множество дисков } BEGIN TestDrives( HD ); { анализ дисков } for c:='A' to 'Z' do if с in HD then WriteLn(c, ':' ); ReadLn { пауза до нажатия клавиши ввода } END. |
Рис. 16.14 (окончание)
6.6. Организация субпроцессов и резидентных программ
Операционная система MS-DOS обладает мощной способностью организовывать субпроцессы. Это означает, что одна программа может запустить другую, а та, в свою очередь, еще одну и т.д. Запускающая программа (процесс), включив работу субпроцесса, сама как бы замирает (но остается в памяти ПЭВМ). Субпроцесс выполняется в оставшейся памяти как любая другая программа. После его завершения вновь «оживает» процесс более высокого уровня.
Это свойство MS-DOS позволяет создавать программы-интеграторы. В них содержатся, как правило, меню запускаемых программ с комментариями и сами запуски этих программ, т.е. команды организации субпроцессов. Популярная программа Norton Commander, например, является нормальной нерезидентной программой, активно использующей субпроцессы (будь то запускаемые из нее файлы или подкачка программ типа dbview.exe).
Нормальные программы после завершения работы освобождают память ПЭВМ. Субпроцессы после их завершения передают управление вызвавшим их программам, а те, в конце концов, передают управление ОС.
Иначе работают так называемые резидентные программы. После запуска они могут выполнить сразу какие-либо действия, а могут {375} ограничиться только скрытыми «махинациями» с прерываниями ОС. Основная их особенность в том, что после завершения своей работы они остаются в памяти ПЭВМ, и оживают лишь при выполнении каких-либо условий. Как правило, резидентные программы настраивают на себя определенные векторы прерываний (сигнал с клавиатуры, обращение к диску, запуск программы и т.п.), анализируют, что произошло, и при необходимости выполняют заложенные в них действия. Примеров резидентных программ можно привести множество. Здесь и система SideKick, и драйверы кириллицы ALFA, BETA, антивирусные программы и сами вирусы, а также многое другое. Объединяет их одно: они все находятся в ОЗУ и «оживают» лишь при специальных условиях (нажатии определенной клавиши, например, ALFA, BETA; обращении к диску — антивирусные программы-защитники, наступлении заданного времени — программы расписаний и т.п.). В пассивном состоянии резидентные программы только занимают место и не мешают нормальным программам работать (в том числе вызывать субпроцессы и т.д.).
При написании программ с вызовом субпроцессов или резидентных программ на Турбо Паскале всегда необходимо предварительно рассчитывать требования к памяти конкретной программы. По умолчанию считается, что программа может работать со всей свободной на момент запуска памятью (рис. 16.15).
640K
Отводимая
для работы
программы
свободная память
(стек
и куча)
Код
и данные
запущенной
программы
РЕЗИДЕНТНЫЕ
ПРОГРАММЫ
DOS
xxK
0K
Рис. 16.15
Эта свободная память используется для локальных переменных процедур и функций и для динамических переменных (созданных {376} процедурами New и GetMem). В ней не могут быть организованы субпроцессы. А другой свободной памяти нет. Выход один — указать явно отводимый размер памяти (рис. 16.16).
640K
Отводимая
для работы программы свободная память
(стек и куча)
Код
и данные
запущенной
программы
РЕЗИДЕНТНЫЕ
ПРОГРАММЫ
DOS
xxK
0K
Свободная
память
Рис. 16.16
Теперь в свободной памяти можно организовывать субпроцессы. Похожая картина имеет место и с резидентными программами. Если не ограничить «аппетит» программы, то она останется резидентной, но отведет под себя всю оставшуюся память. При этом другие программы запускаться не будут — негде.
В Турбо Паскале для управления памятью служит ключ компилятора $М. Он должен стоять до первой строки текста на Паскале в основной программе (в модулях он не имеет смысла):
{$М Стек, МинимумКучи, МаксимумКучи }
Этот ключ детально обсуждался в разд. 11.4. На месте первого параметра должно стоять число в интервале от 1024 до 65520 (1K...64K) — это память для стека. Второй параметр — Минимум-Кучи — это число, показывающее минимальный размер требуемой свободной памяти (обычно это 0, максимальное значение — 655360 (640K). Если на момент запуска программы свободной памяти в ПЭВМ будет меньше чем МинимумКучи, то она не сможет работать и остановится с сообщением о невозможности выполнения. Последним идет максимальный размер кучи. Его диапазон тот же: от 0 до 655360 (0K...640K), но не меньше чем МинимумКучи. {377}
Задавая размеры кучи, не следует заботиться об уже находящихся в памяти программах и вычислять, сколько места они занимают. Если для кучи выделено параметром МаксимумКучи места больше, чем реально осталось в памяти, то его значение будет автоматически сокращено. Основной задачей для разработчика программы является определение разумных ресурсов стека и кучи. Размер стека можно оценить, просуммировав размеры локальных переменных в процедурах и функциях самой «глубокой» по уровням вложенности цепочки их вызовов и найдя максимальное для программы значение этой суммы. Проще найти требуемые размеры кучи. Для этого надо просуммировать размеры динамических переменных (объектов), созданных при выполнении процедур New и GetMem. Заметим, что ограничившись этой суммой, надо далее идеально использовать память кучи, т.е. не оставлять в ней пустот между динамическими объектами, стирая некоторые из них. В противном случае, если куча будет «дырчатой» (разрывной), в нее могут не уместиться объекты, более крупные, чем максимальный свободный блок в ней, даже если сумма этих зазоров будет достаточно велика.
Тем не менее полученные числа для размеров стека и кучи вполне можно взять за начальные приближения. Если же они окажутся малы, то возникнут ошибки времени выполнения: 202 — переполнение стека и 203 — переполнение кучи (при отладке программ рекомендуем включать в них директиву проверки переполнения стека {$S+}).
Пусть, к примеру, вычисленные предварительно размеры стека и кучи будут равны 968 байт и 2000 байт соответственно. Тогда директива $М может иметь вид
{$М 1024, 0, 2048}
Значения округлены в большую сторону до целого числа килобайтов. Вместо 0 можно, в принципе, поставить любое число, не превышающее максимальное значение кучи (здесь до 2048).
Программа, не имеющая вызовов New или GetMem внутри себя и во внешних библиотеках, подключаемых через директиву USES, кучи не использует, и может иметь директиву типа
{$М 4096, 0, 0}
Установив директиву использования памяти, можно далее применять специальные процедуры (табл. 16.7) для организации субпроцессов и резидентных программ. {378}
Процедуры |
Назначение |
SwapVectors |
Восстанавливает системные либо временные векторы прерываний для запускаемых субпроцессов |
Exec(ExeFile, ComLine : String) |
Запускает выполнимый файл ExeFile (субпроцесс) со строкой параметров ComLine |
Функция DosExitCode : Word |
Возвращает код завершения субпроцесса |
Keep(ExitCode : Word) |
Завершение программы без стирания ее из памяти ПЭВМ (организация резидентного кода) |
