Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СТА (лекции+лабы) / СТА Лекция 1.docx
Скачиваний:
50
Добавлен:
16.03.2016
Размер:
336.41 Кб
Скачать

Модель памяти в прикладных программах

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

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

Виртуальная память любой программы логически разделяется на 4 области, каждая из которых имеет совершенно различное предназначение:

  • сегмент кода (code segment);

  • сегмент данных (data segment);

  • сегмент стека (stack segment);

  • куча (heap).

При запуске программы с диска или другого постоянного накопителя в сегмент кода (code segment) из исполняемых файлов и используемых ими динамически подключаемых библиотечных модулей (DLL - Dynamic Linked Libraries) загружаются машинные инструкции, полученные ранее в процессе сборки программ. Центральный процессор выполняет именно эти инструкции. Также в сегменте кода размещаются константные глобальные данные, например, строковые литералы.

Сегмент кода доступен программам только для чтения. Любая попытка программы осуществить запись по адресам в сегменте кода приведет к фатальному завершению программы. Это легко продемонстрировать на строковых литералах:

Intmain ()

{

char* s = "hello Code Segment!";

s[ 0 ] = 'H';

}

Содержимое строки будет размещено в сегменте кода. Вторая инструкция приведет к фатальному завершению, при этом среда выполнения сообщит о нарушении прав доступа к памяти:

В сегменте данных(data segment), также называемом статической памятью, размещаются переменные, существующие от начала работы до завершения программы. К таким переменным относятся глобальные, а также статические локальные переменные функций (переменные, сохраняющие свое значение между вызовами). Обычно все такие переменные соседствуют в памяти. В случае неаккуратной манипуляции с адресами в данной области можно непроизвольно изменить другую переменную такого же типа:

#include <iostream>

int a = 1, b = 2;

Int main ()

{

int * p = & a; // берем адрес глобальной переменной

*( p + 1 ) = 3; // модифицируем соседнюю ячейку - место хранения b

std::cout << b << std::endl; // выведет 3

}

Сегмент стека(stack segment), также называемый автоматической памятью, содержит локальные переменные и аргументы функций. Также при вызовах функций здесь размещается служебная информация, такая как состояние регистров процессора до вызова для последующего восстановления, адрес инструкции в сегменте кода для возврата после завершения работы вызванной функции, адрес переменной-результата для больших объектов и др. Стек заполняется снизу вверх по мере необходимости, в зависимости от характера вызовов функций и содержащихся в них переменных и связанных служебных данных. При выходе из функции задействованная ей память в стеке считается свободной и может быть использована другими функциями.

Ниже представлено содержимое стека в 3 момента времени, соответствующие состояниям до вызова функции f, внутри его и после возврата в функцию main:

void f ( int x )

{

int y = x + 4; // Точка 2

// ...

}

Соседние файлы в папке СТА (лекции+лабы)