П О Р Т А Л                            
С Е Т Е В Ы Х                          
П Р О Е К Т О В                        
  
Поиск по сайту:
                                                 
Главная

О проекте

Web-мастеру
     HTML & JavaScript
     SSI
     Perl
     PHP
     XML & XSLT
     Unix Shell

MySQL

Безопасность

Хостинг

Другое








Самое читаемое:

Учебник PHP - "Для Чайника".
Просмотров 178146 раз(а).

Иллюстрированный самоучитель по созданию сайтов.
Просмотров 75594 раз(а).

Учебник HTML.
Просмотров 74080 раз(а).

Руководство по PHP5.
Просмотров 45005 раз(а).

Хостинг через призму DNS.
Просмотров 51934 раз(а).

Подборка текстов стандартных документов.
Просмотров 45110 раз(а).

Учебник PHP - Самоучитель
Просмотров 51340 раз(а).

Документация на MySQL (учебник & справочное руководство)
Просмотров 51794 раз(а).

Внешние атаки...
Просмотров 41935 раз(а).

Учебник PHP.
Просмотров 37278 раз(а).

SSI в примерах.
Просмотров 27848 раз(а).






 
 
| Добавить в избранное | Сделать стартовой Project.Net.Ru | Помощь





Распределение памяти

 

Что такое программа?

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

 

Различные области

Чтобы понять, что происходит при выполнении двоичного кода, давайте посмотрим на организацию памяти. Она зависит от различных областей:

распределение памяти

Вообще говоря это не все, однако мы рассмотрим только те части, которые наиболее важны в этой статье.

Команда size -A file --radix 16 выдает размер каждой области, зарезервированый при компиляции. Отсюда можно взять адреса областей в памяти (вы можете также использовать команду objdump, чтобы узнать эти данные). Вот вывод size для двоичного файла "fct":

>>size -A fct --radix 16
fct  :
section            size        addr
.interp            0x13   0x80480f4
.note.ABI-tag      0x20   0x8048108
.hash              0x30   0x8048128
.dynsym            0x70   0x8048158
.dynstr            0x7a   0x80481c8
.gnu.version        0xe   0x8048242
.gnu.version_r     0x20   0x8048250
.rel.got            0x8   0x8048270
.rel.plt           0x20   0x8048278
.init              0x2f   0x8048298
.plt               0x50   0x80482c8
.text             0x12c   0x8048320
.fini              0x1a   0x804844c
.rodata            0x14   0x8048468
.data               0xc   0x804947c
.eh_frame           0x4   0x8049488
.ctors              0x8   0x804948c
.dtors              0x8   0x8049494
.got               0x20   0x804949c
.dynamic           0xa0   0x80494bc
.bss               0x18   0x804955c
.stab             0x978         0x0
.stabstr         0x13f6         0x0
.comment          0x16e         0x0
.note              0x78   0x8049574
Total            0x23c8

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

Перед объяснением предназначения других областей, вспомним кое-что о переменных в Си. Глобальные переменные используются во всей программе, в то время как локальные переменные - только в функциях, где они определены. Статические переменные имеют известный размер, зависящий от их типа, при их определении. Тип может быть char, int, double, указатель и т.д. На машине типа PC, указатель представляет собой 32-х битный целый адрес в памяти. Размер области на который он указывает не известен явно при компиляции. Динамическая переменная представляет собой явно выделенную область памяти - на самом деле, это указатель, указывающий на этот выделенный адрес. Глобальные/локальные, статические/динамические переменные могут быть комбинированы без всяких проблем.

Вернемся к организации памяти для данного процесса. Область data содержит инициализированные глобальные статические данные (значения предоставляются во время компиляции), в то время как сегмент bss содержит неинициализированные глобальные данные. Эти области зарезервированы при компиляции, т.к. их размеры определены в соответствии с объектами, которые они хранят.

А что насчет локальных и динамических переменных? Они сгруппированы в область памяти, зарезервированную для выполнения программы (стековый фрейм пользователя). Т.к. функции могут вызываться рекурсивно, количество экземпляров локальных переменных заранее неизвестно. При их создании, они будут помещены в стек. Этот стек находится в области высших адресов в адресном пространстве пользователя и работает по принципу LIFO(Последний вошел, первым вышел). Нижняя часть области пользовательского фрейма используется для размещения динамических переменных. Эта область называется "куча": она содержит память, адресуемую указателями, и динамические переменные. При объявлении, указатель - это 32-х битная переменная в BSS или в стеке, не указывающая ни на какой действительный адрес. Когда процесс выделяет память (например используя malloc), адрес первого байта этой памяти (также 32-х битное число) помещается в указатель.

Назад | Содержание | Вперед



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





Copyright © 2005-2016 Project.Net.Ru