Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Паскаль(методичка).doc
Скачиваний:
36
Добавлен:
09.11.2019
Размер:
1.27 Mб
Скачать

Распределение памяти при выполнении программы

Верхняя граница памяти

FrePtr

Свободная память

HeapPtr

Область для динамических переменных (куча)

OvrHeapEnd

Она заполняется вверх от отметки

вверх

Верхняя граница стека

OvrHeapOrg

Занятая динами ческая память

HeapOrg

Область памяти оверлеев (оверлейный буфер, если он необходим).

Sseg : Str

Стек, для хранения локальных переменных и параметров процедур и функций

Заполненая часть стека

Sseg : 0000

Заполняется вниз

Свободная часть стека

Сегмент данных

Глобальные переменные

Dseg : 0000

Типизированные константы.

Сегмент кода модуля System.

Если он есть в программе

Cодержимое регистров CS, DS, SS не изменяется в ходе программы! А SP-снижается вниз пока не достигнет конца!

Здесь содержится образ EXE файла

Сегмент кода первого модуля (Unit)

Cегмент кода других модулей.

Сегмент кода последнего модуля (Unit)

Cseg : 0000

C егмент кода основной программы.

Стандартная переменная

PrefixSeg = 0000

Начальный адрес программы

Префикс сегмента программы (PSP) = 256 байт

Это файл анкета о загружаемой программе

После PSP (ProgramSegmentPrefix) располагаются коды EXE-файла – это может быть один сегмент = 64 кбайтам. Если программа разбита на модули, то каждому модулю соответствует свой сегмент кода программы. За СЕГМЕНТОМ КОДА ОСНОВНОЙ ПРОГРАММЫ располагаются сегменты в порядке, обратном тому, который указан при вызове в разделе USES.

Затем располагается СЕГМЕНТ КОДА МОДУЛЯ System. После следует СЕГМЕНТ ДАННЫХ – все константы, переменные (глобальные).

За СЕГМЕНТОМ ДАННЫХ следует СЕГМЕНТ СТЕКА.

Назначение сегмента стека:

1.при вызове процедур и функций он служит для передачи параметров;

2. здесь размещаются все локальные переменные на уровне процедур и функций;

3.здесь сохраняются все критические значения программы.

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

Пример программы распределения памяти и получения доступа к полям psp.

{Программа, демонстрирующая распределение памяти}

program Demo_Size;

uses Crt;

var

P : pointer;

I : word; procedure ProgSize;

var

SysemTotalSize : word {Общий размер кучи}

PrefixSize : word {Размер PSP}

CodeSize : word {Размер сегмента кода}

DataSize : word {Размер сегмента данных}

HeapSIze : word {Размер динамической памяти}

AllocHeapSize: word {Размер занятой части динамической памяти}

Factor : real ;

S : string[80] ;

LI : byte absolute S;

1,1 : byte;

function Lin_Adr (P : pointer) : longint; {Вычисление абсолютного (линейного) адреса объекта по обычному сегментному адресу}

begin

Lin_Adr:=longint(Seg(P^)*16+0fs(Р^);

end;

begin {Начало процедуры}

SystemTotalSize := 640*1024 div 16;

PrefixSize := 256 div 16;

CodeSize := Dseg — PrefixSeg — PrefixSize;

DataSize := SegtHeapOrg^ — SSeg;

HeapSize ;= Mem[PrefixSeg:2] - Seg (HeapOrg^);

AllocHeapSize := (Lin_Adr(HeapPtr)-Lin_Adr(HeapOrg)+1) div 16;

Writein (' Распределение памяти: ');

Factor := 67 / SystemTotalSize;

L:= Round(Factor*PrefixSize) ;

FillChar(S[l],L,#176) ;

Writeln ('PSP ',PrefixSize:5,' ',S);

L := Round(Factor*CodeSize) ;

FillChar(S[l],L,#176) ;

Writeln('Код ',CodeSize:5,' ',8);

L := Round(Factor*DataSize) ;

FillChar(S[l],L,#176) ;

Writeln ('Данные ',DataSize:5,' ',S);

L := Round(Factor*HeapSize) ;

LI := Round(Factor*AllocHeapSize) ;

FillChar(S[l],LI,#176) ;

FillChar(S[LI+l],L-LI,#219) ;

Writein ('Куча:', HeapSize: 5,' ',S);

Writein end;

begin {Основная программа}

Randomize;

for I:=l to 100 do {Попробуйте поменять конечное значение параметра I (от 1 до 1000)}

GetMam(P,Random(1000)); {Занимаем часть динамической.памяти блоками случайных размеров}

ProgSize; {Выводим на экран карту памяти}

end.

Порядок выполнения работы

  1. Изучить теоретические сведения по теме: “Изучение карты памяти. Разработка программы доступа к полям PSP”.

  2. Изучить программу распределения памяти и доступа к полям PSP.

  3. Показать работающую программу преподавателю.

  4. Ответить на контрольные вопросы.

Контрольные вопросы

  1. Адреса MS-DOS. Абсолютный адрес, сегмент, смещение.

  2. Карта распределения памяти при выполнении программы.

  3. Сегмент кода, сегмент данных, сегмент стека. Назначение каждого из сегментов.

Лабораторная работа № 32

Разработка программы использования динамической памяти

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

Краткие теоретические сведения

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

• сама программа пользователя;

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

• определяемые пользователем структуры данных и константы;

• точки возврата для подпрограмм;

• временная память для хранения промежуточных результатов при вычислении выражений;

• временная память при передаче параметров и т.п.

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