Методические указания и задания к лабораторным работам для учащихся ссуз специальности Т1002 «Программное обеспечение информационных технологий»

Вид материалаМетодические указания

Содержание


Порядок выполнения работы
Контрольные вопросы
Лабораторная работа № 31 Изучение карты памяти. Разработка программы доступа к полям PSP
Краткие теоретические сведения
Распределение памяти при выполнении программы
PSP (ProgramSegmentPrefix) располагаются коды EXE-файла
Сегментом кода основной программы
Сегмент данных
Пример программы распределения памяти и получения доступа к полям PSP.
Подобный материал:
1   ...   24   25   26   27   28   29   30   31   32

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

  1. Изучить теоретические сведения по теме “ Разработка программы для работы с нетипизированным файлом”.
  2. Получить у преподавателя индивидуальное задание и разработать программу для работы с нетипизированным файлом согласно заданному варианту.
  3. Показать работающую программу преподавателю.
  4. Ответить на контрольные вопросы.

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

  1. Понятие нетипизированного файла. Описание нетипизированного файла.
  2. Средства работы с нетипизированными файлами.
  3. Пример программы для работы с нетипизированными файлами.



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

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



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

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


Чтобы более полно представить все процессы, протекающие внутри любой программы на Паскале, необходимо знать расположение ее внутренних областей в памяти. Для каждой отдельной программы при ее запуске (загрузке в память) MS-DOS организует в памяти что-то вроде анкеты (длинной в 256 байт). Это файл, называемый префиксом программного сегмента (Program Segment Prefix (PSP)).

Система адресации MS-DOS.


ПЗУ

16 блоков по 64 кб каждый



От F0000 до FFFFF

О
Область кассет ПЗУ
т E0000 до ……..

О
Расширение BIOS
т D0000 до ……..

От C0000 до ……..

В
память дисплея


А

9
Рабочее ОЗУ (10 блоков 640 кб)


Обычно под OS


0000

…………………..

10000

00000


Блок или сегмент обозначается 16-ричной цифрой, обозначающей старшую цифру адреса. 0-блок – это адреса: от 00000 до 0FFFF. Абсолютный адрес – это адрес без учета сегментов, он не может быть > FFFFF. Физический адрес = Абсолютный адрес + Смещение. Абсолютный адрес - адрес самого сегмента (16 бит = 2 б). Смещение – адрес внутри сегмента (4 бита). Это содержимое сегментного регистра.

Таким образом, адрес любой ячейки памяти определяется парой чисел:

СЕГМЕНТ:СМЕЩЕНИЕ.

Знак $ - предшествует 16-ой записи числа.

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


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

О
FrePtr

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

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


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

О
вверх

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

OvrHeapOrg

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

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


З
Sseg : Str

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

С
Sseg : 0000

Заполняется вниз
вободная часть стека

Г
Сегмент данных
лобальные переменные

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


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

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

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

Здесь содержится образ EXE файла
егмент кода первого модуля (Unit)


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

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

C
Cseg : 0000

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


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

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.