Разное
Последние книги
Самое популярное
Все бесплатно
Все ссылки на файлы, расположенные на страницах сайта, добавлены пользователями и доступны для бесплатного скачивания. За содержание этих файлов администрация сайта ответственности не несет.
Навигация
Вопросы
К-во рабочих дней в месяце
Категория: Математика
Категория: Математика
Проверить существование определённого URL
Категория: Базы данных
Категория: Базы данных
Сохраняем Bitmap в поле dbase
Категория: Базы данных
Категория: Базы данных
Перевод символа в верхний или нижний регистр для русского алфавита
Категория: Текст и строки
Категория: Текст и строки
Что такое хук (hook)?
Категория: Приложение
Категория: Приложение
Как нарисовать календарь
Категория: Текст и строки
Категория: Текст и строки
Определение размера файла
Категория: Файловая система
Категория: Файловая система
Узнать запущен ли сервис FireBird
Категория: Интернет и Сети
Категория: Интернет и Сети
Listbox - элементы вверх-вниз
Категория: Компоненты
Категория: Компоненты
Создать *.mdb-файл и таблицу в ней
Категория: Базы данных
Категория: Базы данных
Assembler and Win32
Assembler&Win32. Курс молодого бойца. Урок 2.
Память системы
Прежде чем рассказывать, о языке ассемблера я
расскажу вам, как устроена память на Win32 системах. Программировать на
ассемблере не зная, как устроена память системы бессмысленно. Самое
главное преимущество ассемблера состоит во взаимодействии с памятью.
Ладно, приступим. Сначала я объясню, что такое смещение. Смещение это положение относительно чего-то. Смещение может быть в файле, в памяти и вообще во всём. Если говорить по-другому, то смещение это положение, адрес, местонахождение всегда измеряется в байтах. У каждой переменной есть смещение, у каждой команды есть смещение.
Немного истории.
Теперь о памяти. В ДОС и в windows 3.Х память была сегментной. Вся память делилась на сегменты по 64 КВ., и адрес (именно адрес, а не смещение) задавалась, форматом сегмент: офсет. Сегмент задаёт порядковый номер сегмента, а офсет задаёт смещение чего-либо в этом сегменте.
Учтите, что это объяснение для 16-разрядных программ, о 32-разрядных я расскажу позже, (но не пропускайте эту часть, важно понять, что такое 32-разрядность).
Таблица выше иллюстрирует общую память, разделенную на сегменты по 64kb. Здесь максимум 65536 сегментов. Теперь возьмите один из сегментов:
Вы спросите, зачем нужна эта сегментность. Всему есть разумное объяснение. Дело в том в том, что ДОС 16 битный. И регистры 16 битные. С помощью 16 бит можно адресовать только 65536 байт памяти и 65536 сегментов.
Например:
0030:4012 (всё шестнадцатиричное)
Это означает: сегмент 30, смещение 4012. Чтобы узнать, что находится в том адресе, вы сначала переходите на сегмент 30, а затем в сегменте смещаетесь на 4012. В предыдущих уроках мы узнали о сегментных и указательных регистрах. Например, сегментные регистры:
CS - Сегмент кода
DS - Сегмент данных
SS - Сегмент стека
ES - Дополнительный сегмент
FS - Универсальный сегмент
GS - Универсальный сегмент
Названия говорят о их функциях: сегмент кода (CS) содержит номер секции, где вылнен текущий код. Сегмент данных для получения данных из текущего сегмента. На стек указывает сегмент стека (SS) (подробнее о стеке я раскажу позже), ES, FS, GS - универсальные регистры и могут использоваться для любого сегмента (не в win32).
Ладно, приступим. Сначала я объясню, что такое смещение. Смещение это положение относительно чего-то. Смещение может быть в файле, в памяти и вообще во всём. Если говорить по-другому, то смещение это положение, адрес, местонахождение всегда измеряется в байтах. У каждой переменной есть смещение, у каждой команды есть смещение.
Немного истории.
Теперь о памяти. В ДОС и в windows 3.Х память была сегментной. Вся память делилась на сегменты по 64 КВ., и адрес (именно адрес, а не смещение) задавалась, форматом сегмент: офсет. Сегмент задаёт порядковый номер сегмента, а офсет задаёт смещение чего-либо в этом сегменте.
Память | ||||
Сегмент 1 |
Сегмент 2 |
Сегмент 3 |
Сегмент 4 |
и так далее |
Учтите, что это объяснение для 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-разрядным. Так что теперь вы можете забыть о сегментных регистрах
и сосредоточиться на других регистрах.
Выделение памяти.
Если вам даётся 2ГБ памяти, то это не означает, что вы можете обратиться к любому участку памяти. Для того чтобы получить доступ к некоторому участку памяти надо сначала её зарезервировать. Грубо говоря, перед резервированием памяти, резервируемого участка памяти просто не существует (я не оговорился её просто не существует), вы как бы его создаёте и задаёте ему атрибуты доступа (полный доступ, только чтение, только запись, нет доступа). Минимальный размер выделяемой памяти - страница, равна 1000 байтам (для тех, кто не привык к шестнадцатеричной записи, это 4096 байт - 4КБ). Даже если вы захотите выделить 5 байт, то всё равно выделится 4КБ. Такой метод распределения памяти называется гранулярность. Думаю, вы не столкнётесь с тем, что вам надо будет выделять память, лично мне это ни разу не пригодилось. Это нужно при работе с файлами для того, что бы в эту память читать файл.
Не расслабляемся, читаем следующий, урок.
Общая схема памяти в Win32
Выделение памяти.
Если вам даётся 2ГБ памяти, то это не означает, что вы можете обратиться к любому участку памяти. Для того чтобы получить доступ к некоторому участку памяти надо сначала её зарезервировать. Грубо говоря, перед резервированием памяти, резервируемого участка памяти просто не существует (я не оговорился её просто не существует), вы как бы его создаёте и задаёте ему атрибуты доступа (полный доступ, только чтение, только запись, нет доступа). Минимальный размер выделяемой памяти - страница, равна 1000 байтам (для тех, кто не привык к шестнадцатеричной записи, это 4096 байт - 4КБ). Даже если вы захотите выделить 5 байт, то всё равно выделится 4КБ. Такой метод распределения памяти называется гранулярность. Думаю, вы не столкнётесь с тем, что вам надо будет выделять память, лично мне это ни разу не пригодилось. Это нужно при работе с файлами для того, что бы в эту память читать файл.
Не расслабляемся, читаем следующий, урок.