Директивы FAR и NEAR
Как правило, компилятор Turbo Pascal автоматически выбирает адресацию к подпрограмме. Например, если подпрограмма находится в одном файле с основной программой, то она компилируется с "ближним" (near) адресом входа и возврата, состоящим только из смещения в текущем сегменте, а если она находится в модуле, то формируется "дальний" (far) адрес, состоящий из адреса сегмента и смещения.
Так, например, если подпрограмма используется для переменных процедурного типа, она независимо от своего расположения должна компилироваться с получением "дальнего" адреса.
Реже используется директива near, которая сообщает компилятору, что подпрограмму следует компилировать с получением именно такого адреса. Эта директива эквивалентна ключу компилятора {$F-}, который выбирается по умолчанию. Действие директивы распространяется только на одну подпрограмму.
Директива EXTERNAL
Директива external позволяет использовать в программе подпрограммы, написанные на языке ассемблера и скомпилированные отдельно. Эти подпрограммы должны быть скомпонованы с основной программой, используя ключ {$L <имя файла>}. Здесь имя файла - имя того файла (с расширением .OBJ), в котором находятся скомпилированные объектные модули подпрограмм, написанных на языке ассемблера.
Директива ASSEMBLER
Директива assembler позволяет написать подпрограмму полностью на языке ассемблера. При этом во время компиляции подпрограмма будет автоматически скомпилирована встроенным ассемблером пакета Turbo Pascal. При отладке такой подпрограммы можно использовать встроенный отладчик пакета.
Директива INLINE
Директива позволяет включить в текст программы команды, записанные непосредственно в машинных кодах. В отличие от других подпрограмм подпрограмма с директивой inline непосредственно добавляется всюду, где есть ее вызов (фактически она является макроопределением). Такие подпрограммы могут иметь параметры, которые можно использовать в тексте подпрограммы, получая их из стека.
Машинные коды в процедуре записываются в круглых скобках побайтно через прямой слэш (/).
6. Директива INTERRUPT
Директива interrupt предназначена для процедур, обрабатывающих прерывания. Такие процедуры имеют стандартный заголовок:
procedure IntHandler(Flags, CS, IP, AX,
BX, CX, DX, SI, DI, DS, ES, BP: Word); interrupt;
begin
…
end;
В заголовке отдельные параметры можно опускать (но только с начала списка), промежуточные параметры удалять нельзя, например:
procedure IntHandler(DI, ES, BP: Word); interrupt; {неправильный заголовок}
procedure IntHandler(DI, DS, ES, BP: Word); interrupt; {правильный заголовок}
Нельзя в заголовке процедуры обработки прерываний записывать и какие-либо другие параметры.
18.14 Отладка и тестирование программ, содержащих подпрограммы
Практикуются два вида тестирования: нисходящее тестирование и восходящее тестирование. При тестировании программы и ее подпрограмм обычно не обойтись без комбинации этих методов.
18.14.1 Нисходящее тестирование и подпрограммы-заглушки
Независимо от того, как создается программная система (основная программа, в которой имеются подпрограммы), программистом-одиночкой или коллективом программистов, не все подпрограммы обычно бывают готовы одновременно. Тем не менее и при этих условиях возможно выполнить тестирование обмена управляющими сигналами между основной программой и ее подпрограммами первого уровня, а также тестирование и отладку уже готовых программ. Процесс тестирования обмена управляющими сигналами между основной программой и ее подпрограммами называется нисходящим тестированием.
Поскольку для выполнения тестирования основная программа нуждается во всех подпрограммах первого уровня, отсутствующие пока подпрограммы необходимо заменить т.н. подпрограммами-заглушками (stub). Заглушка состоит; головка процедуры или функции, за которым следует тело, содержащее минимум операторов. Эти операторы должны выводить сообщение о выполнении по программы, а также присваивать простые значения любым выходным данным.
18.14.2 Восходящее тестирование и программы-тестеры
Конечно, готовую подпрограмму, если в ней обнаружатся неполадки, всегда можно заменить заглушкой, тем не менее, предварительное тестирование новой подпрограммы следует выполнять обязательно. Искать и исправлять ошибки в отдельной подпрограмме всегда легче, чем в готовой программной системе. Вы сможете протестировать новую подпрограмму, воспользовавшись небольшой программой-тестером.
Не тратьте много времени на создание элегантной программы-тестера — эта программа окажется не нужна в момент, когда тестирование новой подпрограммы будет завершено. Программа-тестер должна содержать только раздел описаний, да минимум операторов, необходимых для тестирования единственной подпрограммы. Данная программа должна начинаться со считывания или присваивания значений всем входным параметрам, а также параметрам входа-выхода, после чего следует вызов тестируемой подпрограммы. В завершение программа-тестер должна отображать результаты работы подпрограммы.
После того как вы уверены, что подпрограмма работает должным образом, замените ее в программной системе заглушкой. Процесс раздельного тестирования самостоятельных подпрограмм, прежде чем собрать их в программную систему, называется восходящим тестированием.
Комбинация восходящего и нисходящего тестирований даст вам уверенность, что программная система после сборки окажется сравнительно свободна от ошибок. В результате заключительная отладка будет выполнена быстро и без проблем.
18.14.3 Рекомендации по отладке программ, содержащих подпрограммы
Вот несколько рекомендаций по отладке программных систем.
- При создании исходного текста не забывайте использовать комментарии для документирования каждого параметра и локального идентификатора подпрограммы. Также используйте комментарии для описания операций, выполняемых подпрограммой.
- Пусть выполнение каждой подпрограммы оставляет след в данных вывода программной системы. Для этого в каждую из подпрограмм, в начале ее тела, поместите оператор WriteLn, который бы отображал сообщение с именем данной подпрограммы.
- В каждую из подпрограмм вставьте операторы, которые при входе в нее отображали бы значения всех входных параметров, а также параметров входа-выхода данной подпрограммы.
- Вставьте операторы, которые бы отображали значения всех выходных данных подпрограммы после передачи управления основной программе. Осуществите ручную проверку этих значений, чтобы убедиться, что они корректны. Для процедур проследите, чтобы все выходные параметры, а также: параметры входа-выхода были объявлены как параметры-переменные.
- Проследите, чтобы подпрограмма-заглушка присваивала значения каждому из выходных параметров.
Очень полезно планировать отладку в процессе создания каждой подпрограммы, а не добавлять отладочные операторы впоследствии. При создании подпрограмм, добавляйте в них отладочные операторы, о которых шла речь в рекомендациях 2 и 4 выше. Когда убедитесь, что подпрограмма работает как нужно, эти операторы несложно будет "изъять из обращения". Для этого проще всего превратить такие операторы в комментарии, заключив их в фигурные скобки, Поэтому же, если возникнут какие-либо проблемы, эти комментарии не составит труда снова сделать исполняемыми операторами, удалив фигурные скобки.
Другой способ включения-выключения отладочных операторов состоит в чтобы использовать глобальную константу типа Boolean (например, Debug), объявленную в основной программе. При этом, когда потребуется отладка, в основной программе должно быть следующее описание данной константы.
const
Debug = True {отладка включена}
А когда надобность в отладке минует, данное описание константы дол выглядеть так:
const
Debug = False {отладка выключена}
Затем в тело основной программы, а также в подпрограммы вставьте диагностические операторы WriteLn, управляемые оператором if с Debug в качестве условия.
18.14.4 Использование отладчика для трассировки процедур
В качестве альтернативы отображению начальных значений входных (и входа-выхода) параметров процедуры с использованием специальных отладочным операторов, для получения соответствующей информации можно воспользоваться отладчиком Turbo Pascal и его возможностью трассировки Trace into (<F7>). Если оператор, который должен быть выполнен следующим, представляет собой оператор вызова процедуры, нажатие клавиши <F7> обеспечит вход в эту процедуру. В результате в окне редактора появится тело этой процедуры с указателем выполнения на слове begin. Если вы укажете параметры процедуры как переменные для наблюдения, исходные значения этих параметров появятся в окне Watch. Затем, с выполнением каждого оператора процедуры (для этого каждый раз требуется . нажимать клавишу <F7>), любое новое значение, присвоенное выходному параметру или параметру входа-выхода, будет отображено в окне Watch.
После того как процедура возвратит управление основной программе, вы можете воспользоваться отладчиком чтобы выяснить, какие значения были возвращены в программу. На этот раз в качестве переменных для наблюдения следует указать все фактические параметры, которые соответствуют выходным параметрам или параметрам входа-выхода. В результате значения, возвращенные процедурой, окажутся отображены в окне Watch.
Дата добавления: 2016-05-28; просмотров: 2677;