Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11656
Последний выпуск: 19.06.2015

Память системы

Автор: Руслан Аблязов
6 октября 2006 года

Прежде чем рассказывать, о языке ассемблера я расскажу вам, как устроена память на Win32 системах. Программировать на ассемблере не зная, как устроена память системы бессмысленно. Самое главное преимущество ассемблера состоит во взаимодействии с памятью.

Ладно, приступим. Сначала я объясню, что такое смещение. Смещение это положение относительно чего-то. Смещение может быть в файле, в памяти и вообще во всём. Если говорить по-другому, то смещение это положение, адрес, местонахождение всегда измеряется в байтах. У каждой переменной есть смещение, у каждой команды есть смещение.

Немного истории.

Теперь о памяти. В ДОС и в windows 3.Х память была сегментной. Вся память делилась на сегменты по 64 КВ., и адрес (именно адрес, а не смещение) задавалась, форматом сегмент: офсет. Сегмент задаёт порядковый номер сегмента, а офсет задаёт смещение чего-либо в этом сегменте.

Память
Сегмент 1 (64kb)Сегмент 2 (64kb)Сегмент 3 (64kb)Сегмент 4 (64kb)и так далее

Учтите, что это объяснение для 16-разрядных программ, о 32-разрядных я расскажу позже, (но не пропускайте эту часть, важно понять, что такое 32-разрядность).

Таблица выше иллюстрирует общую память, разделенную на сегменты по 64kb. Здесь максимум 65536 сегментов. Теперь возьмите один из сегментов:

Сегмент 1(64kb)
Смещение 1Смещение 2Смещение 3Смещение 4Смещение 5и так далее

Вы спросите, зачем нужна эта сегментность. Всему есть разумное объяснение. Дело в том в том, что ДОС 16 битный. И регистры 16 битные. С помощью 16 бит можно адресовать только 65536 байт памяти и 65536 сегментов.

Например: 0030:4012 (всё шестнадцатиричное)

Это означает: сегмент 30, смещение 4012. Чтобы узнать, что находится в том адресе, вы сначала переходите на сегмент 30, а затем в сегменте смещаетесь на 4012. В предыдущих уроках мы узнали о сегментных и указательных регистрах. Например, сегментные регистры:

  • CS - Сегмент кода
  • DS - Сегмент данных
  • SS - Сегмент стека
  • ES - Дополнительный сегмент
  • FS - Универсальный сегмент
  • GS - Универсальный сегмент

Названия говорят о их функциях: сегмент кода (CS) содержит номер секции, где вылнен текущий код. Сегмент данных для получения данных из текущего сегмента. На стек указывает сегмент стека (SS) (подробнее о стеке я раскажу позже), ES, FS, GS - универсальные регистры и могут использоваться для любого сегмента (не в win32).

Теперь о Win32.

В 16-разрядном программировании, сегменты необходимы. К счастью, эта проблема решена в 32-разрядном Windows (95 и выше). Вы все еще имеете сегменты, но вам не нужно заботиться о них, потому, что они уже не 64kb (как в 16-разрядном), а 4 Гб. Windows вероятно даже "повиснет", если вы попытаетесь изменить один из сегментных регистров. Это называеся плоской моделью памяти (flat). Здесь есть только смещения и они теперь 32-разрядные (в диапазоне от 0 до 4,294,967,295). Каждая ячейка в памяти указывается смещением. Это действительно одно из лучших преимуществ 32-разрядного программирования над 16-разрядным. Так что теперь вы можете забыть о сегментных регистрах и сосредоточиться на других регистрах.

Вот общая схема памяти в Win32.

Но 4ГБ может и не быть на машине, поэтому эта память называется виртуальной. Мало того, каждый процесс выполняется в своём виртуальном адресном пространстве. А это значит, что никакой другой процесс не сможет получить доступ к вашей памяти. Для этого существуют специальные API функции, но для их использования нужно иметь специальные привилегии в системе. Память 0-0000FFFF не используется и служит для выявления нулевых указателей, значит, если вы укажете адрес 0000С567, то он будет считаться нулевым, удобно, не правда ли? Любая попытка обратится к этой памяти приводит к ошибке. Память выше 80000000 одна для всех процессов. В этой памяти находится код нулевого кольца, структуры ядра, код планировщика задач, код драйверов, диспетчер ввода вывода, таблица прерываний и т.д. Любая попытка обратиться к памяти ядра приводит к ошибке и к немедленному завершению приложения. Память в диапазоне 00001000-7FFFFFFF доступна для 3 кольца, т.е. для вашего приложения. С ней вы, что хотите то и делаете, в неё также грузятся Дллки.

Выделение памяти.

Если вам даётся 2ГБ памяти, то это не означает, что вы можете обратиться к любому участку памяти. Для того чтобы получить доступ к некоторому участку памяти надо сначала её зарезервировать. Грубо говоря, перед резервированием памяти, резервируемого участка памяти просто не существует (я не оговорился её просто не существует), вы как бы его создаёте и задаёте ему атрибуты доступа (полный доступ, только чтение, только запись, нет доступа). Минимальный размер выделяемой памяти - страница, равна 1000 байтам (для тех, кто не привык к шестнадцатеричной записи, это 4096 байт - 4КБ). Даже если вы захотите выделить 5 байт, то всё равно выделится 4КБ. Такой метод распределения памяти называется гранулярность. Думаю, вы не столкнётесь с тем, что вам надо будет выделять память, лично мне это ни разу не пригодилось. Это нужно при работе с файлами для того, что бы в эту память читать файл.

Не расслабляемся, читаем следующий, урок.


Назад | Оглавление | Далее

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
87K
11 ноября 2012 года
Vladimir Bolonkin
0 / / 11.11.2012
+1 / -0
Мне нравитсяМне не нравится
11 ноября 2012, 22:17:47
То есть, если в сегментном регистре CS будет находится значение, допустим 3h, то этот сегмент будет находится в ОЗУ начиная с адреса 0030h.....
2.
87K
11 ноября 2012 года
Vladimir Bolonkin
0 / / 11.11.2012
+2 / -0
Мне нравитсяМне не нравится
11 ноября 2012, 22:12:23
Сегментный регистр задает не "порядковый номер сегмента", а начало смещения самого сегмента в ПАРАГРАФАХ от начала памяти (адреса - 0000h). А "параграф" - это блок из 16 байт - 00h-0Fh....
3.
1.8K
04 мая 2006 года
Kama
153 / / 04.05.2006
Мне нравитсяМне не нравится
5 ноября 2007, 06:31:40
0030:4012 (всё шестнадцатиричное)

скорей всего это 48 сегмент и 16416 смещение.
4.
9.5K
21 октября 2005 года
quakersasha
23 / / 21.10.2005
Мне нравитсяМне не нравится
23 января 2007, 13:55:30
Да! надо сдвинуть!
5.
11K
06 апреля 2005 года
miron
0 / / 06.04.2005
+2 / -0
Мне нравитсяМне не нравится
24 ноября 2006, 11:39:14
Что то я не понял насчёт диапазона адресов.0-0000FFFF, 00001000-7FFFFFFF и далее. Во втором диапазоне нолик слева не нать двинуть вправо?
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог