10.2. Распределение памяти при выполнении программ
Рассмотрим распределение памяти для выполнимого кода программ на Турбо Паскале (рис. 10.1).
Рис. 10.1
При запуске программы (ЕХЕ-файла) MS-DOS организует в памяти нечто вроде анкеты длиной 256 байт на этот файл, называемой PSP (Program Segment Prefix). Структура PSP описывается в технических руководствах по MS-DOS. Сегмент, с которого начинается отсчет PSP, может быть получен через предопределенную в системной библиотеке (модуле System) переменную PrefixSeg типа Word.
После PSP начинается код ЕХЕ-файла. Он может занимать более одного сегмента. Когда выполняется какой-либо из блоков кода (основной блок, процедуры из модулей), он считается размещенным
- 188 -
в некотором сегменте кода. Реальное значение сегмента при этом содержится в регистре CS процессора.
Статические глобальные переменные основного блока и все типизированные константы, включая локальные, располагаются в сегменте данных, который запоминается регистром DS процессора. Общий объем переменных и типизированных констант не может в сумме превышать 64K.
Заметим, что реальный сегмент может быть и меньше чем 64K. В самом деле, он может начинаться где угодно. Если самый последний байт в нем имеет смещение, например 255 ($00FF), то следующий сегмент может отсчитываться от следующего же байта.
Следом за сегментом данных следует область стека. В ней располагаются локальные переменные и параметры-значения процедур и функций во время их работы по вызову. Сегмент стека содержится в регистре SS процессора. Турбо Паскаль отводит под стек один сегмент, и поэтому область стека не может превышать 64K.
Стек заполняется от своей верхней границы (она может быть назначена директивой компилятору $М) по направлению к началу, т.е. к старту сегмента. Специальный регистр SP процессора содержит смещение указателя стека в сегменте SS (указатель стека — это как бы отметка уровня заполнения стека).
Имеется предопределенная системная переменная StackLimit типа Word, которая логически примыкает к рассматриваемым вопросам. Она содержит минимальное допустимое значение указателя стека. Когда программа запускается, указатель стека имеет максимальное значение, равное отведенной под стек памяти. При работе стек заполняется «сверху вниз», и указатель как бы снижается. Как только он спустится настолько, что свободная часть стека станет меньше чем значение StackLimit, возникнет ошибка времени счета номер 202 Stack overflow (переполнение стека), и программа прервется.
Нормальное значение StackLimit — это 0, а в режиме компиляции {$N+, E+} — 224. Обычно нет необходимости менять это значение.
Выше стека программа отводит себе память под буфер для работы оверлеев — перекрывающихся частей программы. Если они не используются, то буфер не отводится (подробнее об этом см. гл. 18 «Модуль Overlay»).
Еще выше располагается область памяти для размещения динамических переменных и структур данных, называемая областью кучи или просто кучей. Подробное строение кучи будет описано в разд. 11.3.
- 189 -