Как читать память игры c

Обновлено: 07.07.2024

Оперативная память — это память, где временно хранятся данные для быстрого доступа к ним.

Оперативная память позволяет повысить частоту кадров и скорость смены кадров в играх.

При выборе оперативной памяти следует обращать внимание на емкость и скорость.

Также следует знать разницу между форм-факторами, такими как DIMM и SO-DIMM.

Для современных игр нужно не менее 16 ГБ оперативной памяти или больше, если вы используете многозадачность.

Узнайте о том, что такое оперативная память, о разнице между DDR4, SDRAM и DIMM, и о том, как оперативная память влияет на игровой процесс.

Узнайте о том, что такое оперативная память, о разнице между DDR4, SDRAM и DIMM, и о том, как оперативная память влияет на игровой процесс.

Оперативная память (ОЗУ, оперативное запоминающее устройство) — важный компонент любого игрового ПК. Увеличение объема оперативной памяти может повысить быстродействие системы и улучшить частоту кадров по сравнению с системами с меньшим объемом памяти.

Читайте дальше, чтобы узнать, как работает оперативная память, как подобрать совместимые модули, и сколько памяти действительно требуется для игр.

Как работает оперативная память?

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

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

Компьютерам необходим быстрый доступ к временным данным для запуска программ и выполнения задач. Например, современным компьютерным играм нужно быстро загружать графические ресурсы. Игры используют оперативную память для чтения и записи данных, потому что она намного быстрее энергонезависимых накопителей.

Какая оперативная память совместима с вашей системной платой?

Оперативная память SO-DIMM (сверху) обычно используется в ноутбуках или небольших системных платах. Оперативная память DIMM (снизу) используется в стандартных системных платах для настольных ПК.

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

Оперативная память выпускается в виде модулей, которые устанавливаются в разъемы на системной плате. Несовместимая с вашей системой оперативная память не подойдет к разъему или не будет работать надлежащим образом.

Современные системные платы поддерживают модули памяти DDR4. Память DDR4 не следует путать с памятью DDR3, которая представляет предыдущее поколение памяти SDRAM. Эти два типа модулей памяти не являются взаимозаменяемыми, и вы не можете заменить (например) 8 ГБ памяти DDR3 на 16 ГБ памяти DDR4.

DDR4 и SDRAM

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

В современных компьютерах в качестве стандарта используется память DDR4 SDRAM. DDR4 расшифровывается как Double Data Rate 4 (двойная скорость передачи данных 4). Это четвертое поколение технологии DDR, которая заменила технологию SDR (одинарная скорость передачи данных) в памяти SDRAM. Память DDR4 имеет увеличенную скорость передачи данных, увеличенную емкость и более низкое рабочее напряжение по сравнению с памятью предыдущего поколения.

Если вы собираете новый компьютер или заменяете память в относительно новой системе, скорее всего, вам придется иметь дело со стандартной памятью DDR4 SDRAM.

Почему память DDR4 не обладает обратной совместимостью? Потому что она имеет другие тайминги (см. ниже), другое рабочее напряжение, другое количество контактов, а также ряд других отличительных характеристик. Для предотвращения случайной установки шпонка защелки модулей DDR4 расположена не в том же месте, что и у модулей DDR3, то есть, модули DDR4 нельзя вставлять в разъемы DDR3.

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

DIMM (двойной линейный модуль памяти) — это большие модули оперативной памяти, предназначенные для настольных ПК.

SO-DIMM (малый двойной линейный модуль памяти) — это модули памяти меньшего размера, предназначенные для ноутбуков, мини-ПК Intel® NUC и некоторых системных плат малого форм-фактора Mini-ITX (SFF).

Важные характеристики оперативной памяти

  • Емкость: измеряется в гигабайтах (ГБ). Чем больше емкость памяти, тем больше данных могут хранить в ней приложения. При большой емкости оперативной памяти больше приложений могут работать одновременно, а игры могут хранить в ней больше временных данных.
  • Скорость: Скорость памяти измеряется в миллионах операций передачи в секунду (МТ/с), эту единицу часто путают с мегагерцами (МГц), хотя скорость памяти и тактовая частота — разные вещи. Высокая скорость памяти означает более быстрое реагирование на запросы чтения и записи и, следовательно, более высокую производительность.

Сколько оперативной памяти нужно для игр?

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

8 ГБ оперативной памяти считается базовым требованием для игр класса AAA. Однако требования к оперативной памяти растут. Например, в игре Red Dead Redemption 2 рекомендуется наличие 12 ГБ оперативной памяти для оптимальной производительности, а Half-Life: Alyx требует не менее 12 ГБ. Если вам необходим достаточный запас, чтобы играть в новые игры в будущем, рекомендуется установить 16 ГБ оперативной памяти.

Если вы планируете не просто играть, подумайте о 32 ГБ. С таким объемом памяти вы сможете свободно вести прямые трансляции, общаться в чате на Discord и использовать YouTube или Twitch в другом окне.

Если ваш бюджет это позволяет, и вам нужно еще больше оперативной памяти (для 3D-моделирования или других профессиональных приложений), Windows 10 Home и новейшие процессоры Intel® Core™ i9 поддерживают до 128 ГБ. Посмотрите показатель «Максимальный объем памяти» в спецификациях памяти вашего процессора.

Какая мне нужна скорость оперативной памяти?

Ищите подходящий баланс между емкостью и скоростью. Скорее всего, 32 ГБ медленной оперативной памяти не будут идеальным решением, равно как и 4 ГБ быстрой оперативной памяти.

Скорость памяти DDR4 начинается с 1600 МГц, но по сегодняшним стандартам это небольшая скорость. Например, процессор Intel® Core™ i9-10900 поддерживает частоту памяти 2933 МГц в базовой конфигурации.

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

Улучшение производительности будет разным в разных играх, некоторые игры будут работать намного быстрее, в других же разница будет малозаметна. Чтобы оценить необходимость обновления стоит посмотреть результаты тестов со средними показателями частоты кадров.

В дополнение к повышению частоты кадров более быстрая память может обеспечить стабильность частоты кадров и ускорить загрузку кадров. Эти показатели будут представлены в тестах как низкие значения 1 % и 0,1 % (средний наиболее медленный показатель для 1 % и 0,1 % записанных кадров).

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

Другие факторы

Обычно оперативную память приобретают комплектами по два или четыре модуля (например, 2x16 ГБ или 4x8 ГБ). Перед покупкой набора следует посмотреть, сколько разъемов памяти имеется на вашей системной плате.

В настольных ПК обычно бывает четыре разъема памяти, а в ноутбуках — два. На рабочих станциях и ПК для энтузиастов может быть восемь или более разъемов, а в уникальных системах, таких как NUC и SFF, число разъемов может быть разным.

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

Если вы планируете обновить свой ПК в будущем, попробуйте оставить свободные разъемы памяти для будущего расширения, если это возможно. Например, если вы установите комплект 2x16 ГБ вместо 4x8 ГБ, у вас останется два свободных разъема для будущего обновления ПК.

Чтобы воспользоваться преимуществом увеличенной пропускной способности с двухканальной памятью, рекомендуется установить хотя бы одну пару модулей оперативной памяти в симметричные разъемы (обычно они имеют цветовую кодировку). Модули должны иметь одинаковую емкость и желательно одинаковую скорость, т. к. если скорости не совпадают, конечную скорость определяет более медленный модуль памяти.

Что такое двухканальная оперативная память?

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

Двухканальный режим автоматически включается на большинстве системных плат, где имеется только два разъема DIMM. Однако при использовании двух модулей памяти на системной плате с четырьмя разъемами память необходимо устанавливать на тот же канал. Разъемы обычно имеют цветовую кодировку, и могут быть расположены или рядом, или через один. Конкретные указания можно найти в документации по системной плате.

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

Тайминги памяти

Скорость оперативной памяти — не единственный способ оценить ее производительность.

Каждое число соответствует определенному тесту. Например, первое число показывает задержку CAS (задержка строб-импульса адреса столбца) или количество тактовых циклов, за которое модуль памяти возвращает набор данных после получения запроса от контроллера памяти.

Сравнивать модули оперативной памяти исключительно по таймингам может быть довольно сложно. Например, время задержки CAS показывает только общее количество циклов; при оценке быстродействия также имеет значение и длительность каждого цикла. Например, память DDR3 обычно имеет более низкий показатель задержки CAS, чем память DDR4, но ее производительность ниже, потому что она имеет более низкую тактовую частоту.

При сборке игрового ПК тайминги памяти обычно не являются приоритетным фактором. Тайминги представляют интерес для оверклокеров, которые могут вручную понижать их значения в BIOS, а затем тестировать стабильность системы. Если это пройдет успешно, вы сможете добиться более высокой производительности с текущим объемом оперативной памяти.

Для большинства пользователей игровых ПК объем и скорость оперативной памяти являются наиболее важными факторами.

Оверклокинг 1 оперативной памяти

Если вы приобрели высокопроизводительную оперативную память, оверклокинг может помочь выйти за пределы ее расчетных спецификаций. Самый простой способ добиться этого — использовать профили Intel® Extreme Memory Profile (Intel® XMP).

При выборе профиля Intel® XMP в BIOS поддерживаемой системной платы выполняется автоматическая настройка напряжения памяти, тактовой частоты и временных характеристик, за счет чего повышается производительность. Эти заранее определенные настройки уже протестированы и сертифицированы для обеспечения стабильности.

Некоторые системные платы позволяют модифицировать профили памяти и изменять точные настройки памяти вручную, используя BIOS.

Здравствуйте, знатоки! Нужно считать данные из памяти сторонней программы. Использую для этого библиотеку VAMemory.dll.


Адрес предварительно определяю в cheat engine. Но при каждом новом запуске сторонней программы этот адрес меняется. Как можно автоматически определять необходимый адрес? __________________
Помощь в написании контрольных, курсовых и дипломных работ здесь

Получение , запись дампа памяти стороннего процесса.
Можно ли получить дамп памяти стороннего процесса и записать в память этого процесса новые данные?


Чтение памяти процесса
Имеется задача прочитать память некого процесса. Моя сборка для 32-битных систем (не могу перейти.


Чтение памяти чужого процесса
как прочитать всё память процесса . прочитать реальную (допустим от нескольких МБ до нескольких.

Проверка, запущена ли программа (служба) + чтение памяти процесса
Доброго времени суток. Спасибо всем кто, смотрели мою предыдущую тему. (спасибо нажал в ответ:)) .

Как можно автоматически определять необходимый адрес?
  1. Приложение запускается под отладчиком
  2. Находится необходимое место в памяти через тот же Cheat Engine
  3. В отладчике устанавливается условная точка остановки, активирующаяся при изменении значения в найденной памяти
  4. В приложении производятся действия, изменяющие эти значения
  5. В отладчике смотрится дизассемблированный код, который изменяет эти значения. Где-нибудь записывается адрес этого кода
  6. Шаги 4 и 5 повторяются, пока не будут найдены все инструкции, изменяющие требуемую память
  7. Теперь уже пишется трейнер, который куда-нибудь в неиспользуемую память процесса записывает ассемблерные инструкции, которые изменяют (или игнорируют изменение) значения
  8. Все найденные инструкции по сохраненным адресам заменяются на безусловные переходы на инструкции, добавленные в предыдущем шаге (тут несколько шагов: прописать в конец пропатченной инструкции переход обратно в основной код и если инструкция перехода короче чем оригинальная, то "пробелы" заменяются НОПами, чтобы сохранить общий размер исходного кода).

Ого, оказалось все куда сложнее, спасибо за направление!

Добавлено через 3 часа 22 минуты
Это можно сделать в любом отладчике или вы можете посоветовать конкретный?

Да, если он позволяет ставить условные точки остановки на изменение памяти по определенному адресу.

WinDbg, в том же Cheat Engine вроде как встроенный отладчик есть (могу ошибаться). В отладчике смотрится дизассемблированный код, который изменяет эти значения. Где-нибудь записывается адрес этого кода

Запустил приложение отладчиком cheat engine. Установил брейкпоинт на запись по адресу значения в памяти. По разным адресам отладчик всегда выдавал:

5CC4217F - 66 89 0C 58 - mov [eax+ebx*2],cx
729ED419 - 89 17 - mov [edi],edx
729ED42F - 88 07 - mov [edi],al

Вопрос такой: что за двойные адреса инструкций?

Первое — адрес, где инструкция хранится, второе — значение, хранящееся по этому адресу (опкоды и аргументы).

Решение

Ого, оказалось все куда сложнее, спасибо за направление!

- слегка добавлю вариантов попроще.

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

Пробовал искать указатель. Для этого несколько раз находил различные адреса необходимых данных, потом искал для них общий указатель. Ни разу ни один из указателей не был общим хотя бы для 2 адресов.
Забыл указать в начальном посте, что данные из сторонней программы я получаю в строковом виде, и каждый раз они получаются разной длины. Возможно ли, что это есть причина отсутствия указателя на адрес? Потому что для численных данных, вроде как, довольно легко найти указатель на адрес.

Доброго времени суток, эксперты! Удалось найти указатель на адрес с нужными данными. Этим кодом пытаюсь прочитать память процесса.

При попытке считать адрес (add) по указателю (pointer) приходит какая-то шняга, причем неизменная, хотя адрес постоянно меняется. Думаю, что неверно работаю с указателем, буду благодарен за помощь. Заодно такой вопрос, за адрес указателя я принимаю обведенное значение, так ли это?

Решение

Заодно такой вопрос, за адрес указателя я принимаю обведенное значение, так ли это?

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

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

Я так понимаю, обведенный адрес - это 1-ый указатель в цепочке указателей? И что означает стрелка перед ним? В поле слева от стрелки всегда одно и тоже значение: "GameTable.dll"+003CA37C. По идее, стрелка - это как равно, но почему тогда при вычислении программно значение "GameTable.dll"+003CA37C не равно значению, которое обведено?

Добавлено через 8 минут
Upd. тупанул, это же значение по адресу.

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

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

Виды памяти

Существует 3 типа памяти: статический, автоматический и динамический.

Статический — выделение памяти до начала исполнения программы. Такая память доступна на протяжении всего времени выполнения программы. Во многих языках для размещения объекта в статической памяти достаточно задекларировать его в глобальной области видимости.

Автоматический, также известный как «размещение на стеке», — самый основной, автоматически выделяет аргументы и локальные переменные функции, а также прочую метаинформацию при вызове функции и освобождает память при выходе из неё.

Стек, как структура данных, работает по принципу LIFO («последним пришёл — первым ушёл»). Другими словами, добавлять и удалять значения в стеке можно только с одной и той же стороны.

27–28 ноября, Онлайн, Беcплатно

Автоматическая память работает именно на основе стека, чтобы вызванная из любой части программы функция не затёрла уже используемую автоматическую память, а добавила свои данные в конец стека, увеличивая его размер. При завершении этой функции её данные будут удалены с конца стека, уменьшая его размер. Длина стека останется той же, что и до вызова функции, а у вызывающей функции указатель на конец стека будет указывать на тот же адрес.

Проще всего это понять из примера на С++:

Стек при вызове последней рекурсивной функции будет выглядеть следующим образом:


Детали реализации автоматической памяти могут быть разными в зависимости от конкретной платформы. Например, кому очищать из стека метаинформацию функции и её аргументы: вызывающей функции или вызываемой? Как передавать результат: через стек или, что намного быстрее, через регистры процессора (память, расположенную прямо на кристалле процессора. В этой статье не рассматривается, т. к. в языках программирования высокого уровня зачастую нет прямого доступа к регистрам процессора). На все эти вопросы отвечает конкретная реализация calling convention — описание технических особенностей вызова подпрограмм, определяющее способы передачи параметров/результата функции и способы вызова/возврата из функции.

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

Размер автоматической памяти, а он тоже фиксированный, определяется линковщиком (обычно — 1 мегабайт), максимальный размер зависит от конкретной системы и настроек компилятора/линковщика.

Если приложение выйдет за максимум автоматической памяти, его там может ждать Page Fault (сигнал SIGSEGV в POSIX-совместимых системах: Mac OS X, Linux, BSD и т. д.) — ошибка сегментации, приводящая к аварийному завершению программы.

Динамическая — выделение памяти из ОС по требованию приложения.

Автоматическая и статическая память выделяются единоразово перед запуском программы. При их нехватке, либо если модель LIFO не совсем подходит, используется динамическая память.

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

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

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

Максимальный размер динамической памяти зависит от многих факторов: среди них ОС, процессор, аппаратная архитектура в целом, не говоря уже о самом очевидном — максимальном размере ОЗУ у конкретного устройства. Например x86_64 процессоры используют только 48 бит для адресации виртуальной памяти, что позволяет использовать до 256 ТБ памяти. В следующей статье про более низкоуровневую архитектуру памяти будет объяснено, почему не все 64 бита.

Аллокатор

У динамической памяти есть две явные проблемы. Во-первых, любое выделение/освобождение памяти в ОС — системный вызов, замедляющий работу программы. Решением этой проблемы является аллокатор.

Аллокатор — это часть программы, которая запрашивает память большими кусками напрямую у ОС через системные вызовы (в POSIX-совместимых ОС это mmap для выделения памяти и unmap — для освобождения), затем по частям отдаёт эту память приложению (в Си это могут быть функции malloc() / free() ). Такой подход увеличивает производительность, но может вызвать фрагментацию памяти при длительной работе программы.

malloc() / free() и mmap / unmap — это не одно и то же. Первый является простейшим аллокатором в libc , второй является системным вызовом. В большинстве языков можно использовать только аллокатор по умолчанию, но в языках с более низкоуровневой моделью памяти можно использовать и другие аллокаторы.

Например, boost::pool аллокаторы, созданные для оптимальной работы с контейнерами ( boost::pool_allocator для линейных ( std::vector ), boost::fast_pool_allocator для нелинейных ( std::map, std::list )). Или аллокатор jemalloc, оптимизированный для решения проблем фрагментации и утилизации ресурсов CPU в многопоточных программах. Более подробно о jemalloc можно узнать из доклада с конференции C++ Russia 2018.

Способы контроля динамической памяти

Из-за сложности программ очень трудно определить, когда необходимо освобождать память в ОС, и это вторая явная проблема динамической памяти. Если забыть вызвать munmap() или free() , то произойдет следующая ситуация: приложению память уже не нужна, но ОС всё ещё будет считать, что эта память используется программой. Эту проблему называют «утечкой памяти». Существуют несколько способов автоматического или полуавтоматического решения этой проблемы:

RAII (Получение ресурса есть инициализация) — в ООП — организация получения доступа к ресурсу в конструкторе, а освобождения — в деструкторе соответствующего класса. Достаточно реализовать управление памятью в конструкторах и деструкторах, а компилятор вызовет их автоматически. Например, немного урезанный класс String из статьи про Move-семантику. Выделяем память в конструкторе, очищаем в деструкторе:

Умные указатели на основе RAII — указатели, автоматически владеющие динамической памятью, то есть автоматически освобождающие её, когда она больше не нужна. Умные указатели инкапсулируют только управление памятью объекта, но не сам объект, как, например, происходит в String, который инкапсулирует объект целиком. Примеры умных указателей ниже.

std::unique_ptr — класс уникального указателя, является единственным владельцем памяти и очищает её в своём деструкторе. Поэтому объекты класса std::unique_ptr не могут иметь копий, но могут быть перемещены. Подробнее о семантике перемещения в этой статье.

std::shared_ptr — класс общего указателя, использующий атомарный счётчик ссылок для подсчёта количества владельцев памяти. В конструкторе счётчик инкрементируется, в деструкторе — декрементируется. Как только счётчик становится равным нулю, память освобождается.

Но у std::shared_ptr есть проблема, например, когда объект A ссылается на объект B, а объект B ссылается на объект A. В таком случае у обоих объектов счётчик ссылок никогда не будет меньше 1 и произойдёт утечка памяти. Решений у этой проблемы два. Использование std::weak_ptr , который ссылается на объект, но без счётчика ссылок, и не может быть разыменован без предварительной конвертации в std::shared_ptr . Вторым решением этой проблемы является сборщик мусора.

Сборка мусора — одна из форм автоматического управления динамической памятью, которая помечает все доступные из стека или статической памяти динамически выделенные объекты. Объекты, до которых нельзя добраться через цепочку указателей, начиная с автоматической или статической памяти, т. е. не помеченные сборщиком мусора, очищаются.

Умные указатели и RAII используются в основном в относительно низкоуровневых языках, например, С++ или Swift. В более высокоуровневых языках обычно используется сборщик мусора (Java), хотя может применяться комбинация умного указателя и сборщика мусора (Python).

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


Для начала разберемся, что такое сегментные регистры. Процессор 8088 умеет адресовать один мегабайт оперативной памяти, несмотря на то что регистры у него 16-битные. В норме 16 битами можно адресовать только 64 Кбайт. И как же тогда выкручивается 8088? Как ему удается адресовать целый мегабайт? Для этого в 8088 есть сегментные регистры! Четыре сегментных регистра: CS , ES , DS и SS , по 16 бит каждый. У каждого из этих регистров есть свое назначение.

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

Регистры DS и ES указывают на сегмент данных. К этим регистрам процессор обращается, когда выполняемая инструкция считывает или сохраняет данные. Имей в виду: DS используется чаще, чем ES . ES обычно вступает в игру, когда ты обрабатываешь массивы данных, индексируя их регистром DI .

Регистр SS указывает на сегмент стека. К этому регистру процессор обращается, когда выполняет инструкции, взаимодействующие со стеком: push , pop , call и ret .

Значения, хранимые в сегментных регистрах, — это базовый адрес, поделенный на 16 . Если в CS записано значение 0x0000 , процессор будет считывать инструкции из области памяти 0x00000 — 0x0FFFF . Если в регистре CS записано значение 0x1000 , то процессор будет считывать инструкции из области памяти 0x10000 — 0x1FFFF .

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


Поместить какое-то число в сегментные регистры напрямую нельзя. Для этого надо:

  • либо сначала записать число в какой-нибудь регистр и уже этот регистр присвоить сегментному регистру;
  • либо воспользоваться парой инструкций push/pop ;
  • либо воспользоваться инструкциями lds/les .

Процессор 8088 настолько лоялен, что позволит тебе даже вот такую инструкцию: pop cs . Но только имей в виду, что это нарушит поток выполнения инструкций. В более новых процессорах, начиная с 80286, такую диверсию сделать уже не получится. И слава богу!

Ну вот вроде бы и все, что тебе надо знать о сегментных регистрах. Теперь ты с их помощью (в основном с помощью регистров DS и ES ) можешь получать доступ ко всему первому мегабайту памяти ПК.

Как ПК распределяет память

Понимание того, как распределяется память в ПК, поможет тебе делать разные интересные вещи.


Начало загрузки у всех компьютеров одинаковое: они сначала переходят в текстовый цветной режим 80x25 . К видеопамяти экрана, который работает в таком режиме, можно обращаться напрямую, через вот этот диапазон адресов: 0xB8000 — 0xB8FFF .

Первый байт диапазона — это первый символ в верхнем левом углу экрана. Второй байт — это цвет фона под символом и цвет самого символа. Затем (третьим байтом) идет второй символ. И так для всех 25 строк по 80 символов каждая.

Исторический факт. IBM PC образца 1981 года поставлялся в двух модификациях: с монохромным режимом и с цветным режимом. Тогдашним разработчикам игрушек приходилось придумывать разные эвристики, чтобы понять, какая у компьютера графика — монохромная или цветная. Несколько старых добрых игрушек для этого писали какую-нибудь цифру по адресу 0xB8000 и считывали ее обратно, чтобы узнать, в каком режиме сейчас идет работа — в цветном или в монохромном.

Прямой доступ к видеопамяти в текстовом режиме

Перед тем как мы сможем напрямую обращаться к видеопамяти экрана, то есть без использования сервисов BIOS, надо задать нужный нам видеорежим.


В этом режиме видеопамять экрана доступна по адресу 0xB8000 . Теперь ты можешь легко получить доступ к ней. Примерно так, как в коде ниже.


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

Продолжение доступно только участникам

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Читайте также: