Оперативная память ПК, виды, назначение и основные характеристики

Автор работы: Пользователь скрыл имя, 15 Марта 2011 в 21:11, реферат

Описание работы

Оперативная память - это, в отечественной научной терминологии, "оперативное запоминающее устройство" или ОЗУ, а в западной - RAM, то есть "Random Access Memory" ("память с произвольным доступом"). ОЗУ представляет собой область временного хранения данных, при помощи которой обеспечивается функционирование программного обеспечения.

Содержание работы

1.Оперативная память. 3

2.Виды оперативной памяти, их назначение и основные характеристики. 5

2.1 Статическая память 6

3. Устройство матрицы статической памяти 7

4. Типы статической памяти 8

4.2 Динамическая память. 9

5. Процедуры и функции для работы с динамической памятью. 17

Список литературы 21

Файлы: 1 файл

влад.docx

— 153.79 Кб (Скачать файл)

    Как уже отмечалось, параметром процедуры NEW может быть только типизированный указатель. Для работы с нетипизированными  указателями служат процедуры: GETMEM (P, SIZE) — резервирование памяти; О FREEMEM(P, SIZE) освобождение памяти.

    Понятно, что наличие нетипизированных указателей в Турбо Паскале (в стандартном  Паскале их нет) открывает широкие  возможности неявного преобразования типов. К сожалению, трудно обнаруживаемые ошибки в программе, связанные с  некорректно используемыми обращениями  к про- процедурам NEW и DISPOSE, также  могут привести к нежелательному преобразо- преобразованию типов. В  самом деле, пусть имеется программа: {i :- HeapOrg; HeapPtr ;-- HeapOrg + 2} {j :- HeapOrg) {HeapPtr ;- HeapOrg} {r := HeapOrg; HeapPtr -•¦» HeapOrg + бу! i ~i * r : " begin new(i); j := i; Y := 2 dispose new(r) ; Integer; Real; r (i); гл := pi; end.

    Что будет выведено на экран дисплея? Чтобы ответить на этот вопрос, про- проследим за значениями указателя HEAPPTR.

    Перед исполнением программы этот указатель  имел значение адреса начала кучи HEAPORG, которое и было передано указателю I, а затем и J. После выполнения DISPOSE (I) указатель кучи вновь приобрел значение HEAPORG, этот адрес передан  указателю R в процедуре NEW(R).

    После того как по адресу R разместилось вещественное число я = 3,14159, первые 2 байта кучи оказались заняты под часть внутрен- внутреннего представления этого числа. В то же время j все еще сохраняет адрес HEAPORG, поэтому оператор WRITELN(OT) будет рассматривать 2 байта числа л как внутреннее представление целого числа (ведь j — это указатель на тип INTEGER) и выведет 8578. 6.5. Использование указателей Подведем некоторые итоги. Итак, динамическая память составляет 200— 300 Кбайт или больше, ее начало хранится в переменной HEAPORG, а конец соответствует адресу переменной HEAPEND.

    Текущий адрес свободного участка динамической памяти хранится в указателе HEAPPTR Посмотрим, как можно использовать динамическую память для размещения крупных массивов данных. Пусть, например, требуется  обеспечить доступ к элементам прямоугольной  матрицы 100x200 типа EXTENDED Для размещения такого массива требуется память размером 200 000 байт A00x200x10). Казалось бы, эту проблему можно решить следующим образом: var i,j : Integer; PtrArr : array [1..100, 1..200] of AReal; begin for l := 1 to 100 do for j := 1 to 200 do new(PtiArr[i,]l); and. Теперь к любому элементу вновь созданного динамического массива можно обратиться по адресу, например: PtrArr[1,11Л :- 0; if PtrArr[I,j*2JA > 1 then Вспомним, однако, что длина внутреннего представления указателя состав- составляет 4 байта, поэтому для размещения массива PTRARR потребуется ЮОх х200х4 = 80 000 байт, что превышает размер сегмента данных F5 536 байт), доступный, как уже отмечалось, программе для статического размещения данных.

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

    Однако  в Турбо Паскале над указателями  не определены никакие операции, кроме  операций присваивания и отношения. Тем не менее, решить указанную задачу все-таки можно. Как мы уже знаем, любой указатель состоит из двух слов типа WORD, в которых хранятся сегмент и смещение. В Турбо  Паскале определены две встроенные функции типа WORD, позволяющие получить содержимое этих слов: ? SEG(X) — возвращает сегментную часть адреса; ? OFS (X) —  возвращает смещение. Аргументом х  при обращении к этим функциям может служить любая пере- переменная, в том числе и та, на которую  указывает указатель Например, если имеем р : begin new(p); pn := 3.14; end. то функция seg(P) вернет сегментную часть адреса, по которому располага- располагается 4-баЙтный указатель р, в то время  как seg(P") — сегмент 6-байтного участка  кучи, в котором хранится число 3,14.

    Таким образом, возможна такая последовательность действий. Вначале процедурой getmem из кучи забираются несколько фрагментов подходящей дли- длины (напомню, что за одно обращение к процедуре можно зарезервировать не более 65 521 байт динамической памяти). Для рассматриваемого примера удобно резервировать фрагменты такой длины, чтобы в них могли, напри- например, разместиться строки прямоугольной матрицы, т. е. 200x10 = 2000 байт. Начало каждого фрагмента, т. е. фактически начало размещения в памяти каждой строки, запоминается в массиве PTRSTR, состоящем из 100 указателей. Теперь для доступа к любому элементу строки нужно вычислить смещение этого элемента от начала строки и сформировать соответствующий указатель: var Integer; array A , .100J of pointer; PtrStr pr const SizeOfReal begin for l := 1 to 100 do GetMem(PtrStr[i]rSizeOfReal*200); 6; /Обращение к элементу матрицы [i,j]} pr := ptr(seg(PtrStr[i]"), ofs(PtrStr[i.]") + [j-l) *SizeOtReal) ; if pr" > 1 then end.

    Поскольку оператор вычисления адреса PR : = PTR.. . будет, судя по всему, использоваться в программе  неоднократно, полезно ввести вспомогательную  функцию GETR, возвращающую значение элемента матрицы, и процедуру PUTR, устанавливающую  новое значение элемента (правила  объявления про- процедур и функций  изложены в главе 8).

    Каждая  из них, в свою очередь, обращается к  функции ADDRR для вычисления адреса. В примере 6.1 приводится программа, создающая в памяти матрицу из NxM случайных чисел и вычисляющая  их среднее значение. const SizeOfReal = 6; N = 100; М = 200; var l, ] : Integer; PtrStr: array [1..N] of pointer; s : Reel; (Длина переменной типа REAL} {Количество столбцов} {Количество строк} /64 type RealPomt = ~Rcal; {— --) Function AddrR (i,j : word} : RealPoint; {По сегменту i и смещению j выдает адрес вещественной перемерной} begin AddrR := ptr (seg (PtrStr [1] л) , ofs (PtrStr [i]'v) + (j-l) \SizeOfReal) end {AddrR I; { 1 Function GetRA,j: Integer): Real; {Выдает ¦значение вещественной переменной по сегменту i и смещению j ее адреса} begin GetR := AddrR (i.,])A end I GetR); {- ¦-- I Procepure PiitR(i,j - Integer; x- Rpal); {Помещает в  переменную, адрес которой имеет  сегмент i и смещение j, вещественное значение у] begin AddrR (x, j) " -.= х end {PutR); {- } begin (Main! for i :=] to N do begin GetMem(PtrStr[i] ,M^SizeOfRea!) ; for j •= 1 to M do PutR(i, j. Random) end; s := 0; fcr l := 1 to N do for j := 1 to M do s := s + GetR(i, j) ; WriteLn(S / (N * M) : 12:10) end {Mam}.

    В рассмотренном примере предполагается, что каждая строка размещается в  куче, начиная с границы параграфа, и смещение для каждого указателя PTRSTR равно нулю. В действительности при последовательных обращениях к  процедуре GF.TMEM начало очередного фрагмента  следует сразу за концом предыдущего  и может не попасть на границу  сегмента. В результате, при размещении фрагментов максимальной длины F5 521 байт) может возникнуть переполнение при  вычислении смещения последнего байта.

5. Процедуры и функции для работы с динамической памятью.

      Ниже приводится описание как  уже рассмотренных процедур и  функций, так и некоторых других, которые могут оказаться полезными  при обращении к динамической  памяти. Функция addr. Возвращает результат  типа POINTER, в котором содержится  адрес аргумента. Обращение: ADDR (X) Здесь х — любой объект программы  (имя любой переменной, процедуры,  функции). Возвращаемый адрес совместим  с указателем любого типа. Отметим,  что аналогичный результат возвращает  операция.

    Функция CSEG. Возвращает значение, хранящееся в  регистре cs микропроцессора (в начале работы программы в регистре содержится сегмент начала кода программы). Обращение: CSEG Результат возвращается в слове  типа WORD Процедура DISPOSE. Возвращает в  кучу фрагмент динамической памяти, который  ранее был зарезервирован за типизированным указателем. Обращение: DISPOSE(TP) Здесь  ТР типизированный указатель. При повторном  использовании про- процедуры применительно  к уже освобожденному фрагменту  возникает ошибка периода исполнения. При освобождении динамических объектов можно указывать вторым параметром обращения к DISPOSE имя деструктора.

    Функция DSEG. Возвращает значение, хранящееся в  регистре DS микропроцессора (в начале работы программы в регистре DS содержится сегмент на- начала данных программы). Обращение: DSEG Результат возвращается в слове типа WORD 16й Часть I Ядро Турбо Паскаля Процедура ffeemem. Возвращает в кучу фрагмент динамической памяти, кото- который ранее был зарезервирован за нетипизированным указателем. Обращение: FREEMEM (P, SIZE) Здесь: ? р — нетипизированный указатель; ? SIZE — длина в байтах освобождаемого фрагмента.

    При повторном использовании процедуры  применительно к уже освобожденному фрагменту возникает ошибка периода  исполнения. Процедура getmem. Резервирует  за нетипизированным указателем фрагмент динамической памяти требуемого размера. Обращение: GFTMFM (P, ST7F) За одно обращение  к процедуре можно зарезервировать  не более 65 521 байт динамической памяти. Если нет свободной памяти требуемого размера, воз- возникает ошибка периода  исполнения.

    Если  память не фрагментирована, последовательные обращения к процедуре будут  резервировать последователь- последовательные участки памяти, так что начало следующего будет располагаться  сразу за концом предыдущего. Процедура MARK Запоминает текущее значение указателя  кучи HEAPPTR Об- Обращение: MARK (PTR) Здесь PTR — указатель любого типа, в котором  будет возвращено текущее значение HEAPPTR Используется совместно с процедурой RELEASE для освобождения части кучи.

    Функция maxavail. Возвращает размер в байтах наибольшего  непрерывного участка кучи. Обращение: MAXAVAIL Результат имеет тип LONGINT За один вызов процедуры NEW или GETMEM нельзя зарезервировать памяти больше, чем  значение, возвращаемое этой функцией. Функция mema VAIL. Возвращает размер в  байтах общего свободного пространства кучи. Обращение: MEMAVAIL Результат имеет  тип LONGINT Процедура NEW. Резервирует фрагмент кучи для размещения переменной. Обращение: NEW (TP) Здесь тр — типизированный указатель.

    За  одно обращение к процедуре можно  зарезервировать не более 65 521 байт динамической памяти. Если нет свободной  памяти требуемого размера, возникает  ошибка периода исполнения. Если память не фрагментирована, последовательные обращения к процедуре будут  резервировать последователь –  последовательные участки памяти, так  что начало следующего будет располагаться  сразу за концом предыдущего. Процедура NEW может вызываться как функция. В этом случае параметром обращения  к ней является тип переменной, размещаемой в куче, а функция NEW возвращает значение типа "указатель". Например: type Pint -ЛInteger; var р: Pint; begin p = New (Pint) ; end.

    При размещении в динамической памяти объекта  разрешается в качестве второго  параметра обращения к NEW указывать  имя конструктора (см. главу 10). Функция OFS. Возвращает значение типа WORD, содержащее смещение адреса указанного объекта. Вызов: OFS (X) Здесь х — выражение любого типа или имя процедуры. Функция PTR. Возвращает значение типа POINTER по заданному  сегменту SEG и смещению OFS. Вызов: PTR (SEG, OFS) Здесь: О SEG — выражение типа WORD, содержащее сегмент; ? OFS — выражение типа WORD, содержащее смещение.

    Значение, возвращаемое функцией, совместимо с  указателем любого типа. Процедура RELEASE. Освобождает участок кучи. Обращение: RELEASE (PTR) Здесь PTR — указатель любого типа, в котором предварительно было сохранено процедурой MARK значение указателя  кучи. Освобождается участок кучи от адреса, хранящегося в PTR, до конца  кучи. Одновременно уничтожается список всех свободных фрагментов, которые, возможно, были созданы процедурами DISPOSE ИЛИ FREEMEM. Функция SEG.

    Возвращает  значение типа WORD, содержащее сегмент  адреса указанного объекта. Вызов: SEG (X) Здесь х — выражение любого типа или имя процедуры. Функция SIZEOF. Возвращает длину в байтах внутреннего  представления указанного объекта. Вызов: SIZEOF (X) Здесь х — имя  переменной, функции или типа. Например, везде в программе из примера 6.1 вместо константы SIZEOFREAL можно было бы использовать обращение SIZEOF (REAL) 6.7. Администратор кучи

    Как уже отмечалось, администратор кучи — это служебная подпрограмма, которая обеспечивает взаимодействие пользовательской программы с кучей. Администратор кучи обрабатывает запросы процедур NEW, getmem, DISPOSE, FREEMEM и др. и изменяет значения указателей HEAPPTR и FREELIST. Указа- Указатель HEAPPTR содержит адрес нижней границы свободной части кучи, а ука- указатель FREELIST — адрес описателя первого свободного блока. В модуле SYSTEM указатель FREELIST описан как POINTER, однако фактически он указывает на следующую структуру данных: type PFreeRec = "TFieeRac; TFreeRec - record Next : pointer; Size : pointer end, Эта списочная структура предназначена для описания всех свободных блоков па- памяти, которые расположены ниже границы HEAPPTR.

    Происхождение блоков связано со случайной последовательностью  использования процедур NEW—DISPOSE или GETMEM— FREEMEM ("ячеистая" структура  кучи). Поле NEXT в записи TFREEREC содержит адрес описателя следующего по списку свободного блока кучи или ад- адрес, совпадающий с HEAPEND, если этот участок  последний в списке. Поле SIZE содержит ненормализованную длину свободного блока или 0, если ниже адреса, содержащегося  в HEAPPTR, нет свободных блоков., Ненормализованная  длина оп- определяется так: в старшем  слове этого поля содержится количество свободных параграфов, а в младшем  — количество свободных байтов в  диапазоне 0—15.

    Следующая функция преобразует значение поля SIZE в фактическую длину свобод- свободного блока: Function BlockSizelSize: pointer): Longint; {Функция преобразует ненормализованную  длину свободного блока в байты} type PtrRec = record Lo, Hi : word end; var LengthBlock: Longmt; begin BlockSize := Longlnt(PtrRec(Size).Hi)*16 + PtrRec(S.ze).Lo end; Сразу  после загрузки программы указатели heabptr и E'REELIST содержат один и тот же адрес, который совпадает с началом  кучи (этот адрес содер- содержится в указателе HEAPORG) При этом в первых 8 байтах кучи хранится за- запись, соответствующая  типу TFREEREC (поле NEXT содержит адрес, совпа- совпадающий со значением HEAPEND, а  поле SIZE — ноль, что служит дополнительным признаком отсутствия "ячеек" в динамической памяти). При работе с кучей указатели HEAPPTR и FREELIST будут  иметь одинаковые значения до тех  пор, пока в куче не образуется хотя бы один свободный блок ниже границы, содержащейся в указателе HEAPPTR.

Информация о работе Оперативная память ПК, виды, назначение и основные характеристики