Я просто не понимаю. Любое руководство является слишком техническим. Что такое плоская и сегментированная память? Способы обращения к памяти, способы организации байтов в памяти? Какой из них лучше всего подходит для 32-разрядных компьютеров? Может кто-нибудь объяснить это? Что делает режим реального режима и защищенный режим для плоской или сегментированной памяти? Спасибо!
Ответ 1
Если вас интересуют только приложения, работающие на существующих 32/64 битных операционных системах, вы можете просто забыть сегментированную память. В 32-разрядных операционных системах вы можете предположить, что у вас есть 4 ГБ "плоского" пространства памяти. Flat означает, что вы можете манипулировать адресами с 32-битными значениями и регистрами, как и следовало ожидать.
На 16-разрядных процессорах я считаю, что адрес был 20 бит в ширину, и вы не могли сохранить это в регистре, поэтому вам нужно было сохранить базу в одном регистре и указать фактический адрес, вам нужно было добавить смещение к этой базе. (Если я правильно помню, база была умножена на 16, то добавление смещения было добавлено для получения фактического адреса.) Это означает, что вы можете обращаться только к 64 КБ одновременно; память должна быть "сегментирована" в блоках размером 64 КБ.
Честно говоря, я думаю, что единственная причина, по которой новички все еще слышат об этом, состоит в том, что все еще много старых учебников и книг из 16 бит. На самом деле не нужно понимать, как работает программа на уровне сборки. Теперь, если вы хотите изучить разработку ОС, эту еще одну историю. Поскольку ПК запускается в 16-битном режиме, вам нужно будет узнать, по крайней мере, достаточно, чтобы активировать плоский 32-битный режим.
Просто заметил, что вы также спросили о режиме реального режима и защищенном режиме. Реальный режим - это режим, используемый MS DOS. Любая программа имела доступ к любой аппаратной функции, например, было распространено прямое обращение к контроллеру видеокарты для печати. Это не вызвало никаких проблем, поскольку это была не многозадачная ОС.
Но на любой современной ОС обычные программы напрямую не обращаются к аппаратным средствам, они даже не получают доступ к памяти напрямую. ОС управляет оборудованием и решает, какой процесс будет запущен на процессоре (процессорах). Он также управляет виртуальным адресным пространством для каждого процесса. Эта функция доступна с защищенным режимом, который, по моему мнению, пришел с 386, который был первым 32-разрядным процессором для ПК.
Ответ 2
Инструкции о доступе к чему-либо с использованием адреса (память, ввод-вывод, ввод-вывод с памятью и т.д.) иногда обеспечивают полный (с точки зрения адреса этого уровня выполнения процессора) адрес, иногда они обеспечивают смещение. Ваши близкие или относительные прыжки, например, счетчик программ - это базовый адрес, а инструкция обеспечивает смещение этой базы, добавьте их вместе, и вы получите адрес (на этом уровне).
Возьмите 16-битную систему, в которой у вас есть 16-битные регистры и максимальное ограничение на адресное пространство на 64 Кбайта. Очень простой способ расширить эту память - сегментировать. Вместо регистра, содержащего весь адрес, регистр в вашей инструкции содержит смещение базы, подобно команде, связанной с pc. За исключением этого случая существует еще один регистр, который используется в качестве базового адреса. Вы видите это в ряде архитектур, которые хотели бы легко расширить свой диапазон адресов, не слишком сильно, если бы какая-либо модификация ядра. (может быть сделано в контроллере памяти без изменения ядра). В случае x86 было несколько регистров. Один из них использовался для расширения охвата исполнения, веток. Другой способ расширить охват доступа, загрузки и хранения данных. Адрес ветки, не относящейся к ПК, вычислялся с использованием сегмента кода, сдвинутого влево на 4 бита, а затем добавленного в регистр, указанный в инструкции. Для нагрузок и хранилищ, которые не относятся к pc, используется регистр сегмента данных, сдвиг влево 4 добавляет регистр, указанный в инструкции. поэтому, если вы хотите обратиться к 0x123456789, у вас может быть регистр сегмента 0x12340000, а регистр, используемый для адресации, содержит 0x56789, или сегмент 0x12345678 и gpr содержат 0x9. Соответствующая адресация ПК - это, конечно, сегмент + pc + смещение.
Это приводит к принятию различных моделей памяти. маленький, маленький, средний, большой, огромный. Вы можете себе представить, что у самой маленькой модели было бы правило или предполагалось бы в случае x86, что все находится в пространстве памяти 64 КБ, компилятор и ваш код никогда не будут беспокоиться о сегментарных регистрах, предполагается, что они остаются фиксированными. Для больших моделей или при использовании дальнего указателя, идущего дальше, не имеет большого значения, вы устанавливаете сегмент данных, затем устанавливаете смещение данных и выполняете загрузку или сохранение. Для кода вы могли бы представить это немного сложнее, поскольку, как только вы меняете регистр сегмента кода, он влияет на общий адрес, где вы извлекаете инструкции. Возможно, вам понадобится аппаратное решение, позволяющее ветке изменять сегмент и смещение, или вы можете сделать это в коде (если разрешено аппаратное обеспечение). Я не буду путать вас с этим на данный момент.
Всякий раз, когда у вас есть массив в коде:
unsigned char abc[123];
Это в основном то же самое. Базовый адрес, адрес, где массив начинается в памяти, похож на ваш сегмент, а индекс - ваше смещение. Если в приведенном выше abc было по адресу 0x1004, то abc [5] находится по адресу 0x1004 + 5 = 0x1009. Не сдвинуто, как сегмент x86: смещение адресации, но та же концепция добавления базы и смещения. Некоторые сегментированные архитектуры, которые у вас нет, некоторые биты в каком-то регистре где-то являются верхними битами. Возьмите адрес 0x12345 в одной из этих систем. 0x1 должен находиться в сегменте и 0x2345 в 16-битном gpr. Вы можете думать об этом как о смене и добавлять, если хотите, но в отличие от сегмента x86: offset вы также можете думать об этом как о смене и/или.
Плоское пространство памяти - это немного иллюзия, особенно в x86 системах. x86, 32-разрядные и даже многие 64-разрядные, ограничивают объем свободного пространства памяти для подключаемых карт в сумме 1Gig, имеет большое значение для 32-битной системы, где у вас есть 4-х адресное адресное пространство, и поэтому некоторые из них дают вам ограничение в 3 гигабайта или дают вам иллюзию 4-го концерта, но вырезали некоторые из них для плагинов. (многие из ваших материнских плат находятся в этом месте, а также в виде плагинов). В зависимости от видеокарты и разрешения и т.д. Вы иногда не можете вместить весь буфер кадра в подмножество этого периферийного пространства, поэтому вам нужно сегментировать свой доступ. биос, возможно, дал вам адрес 0x80000000 в качестве базы в адресном пространстве x86, затем в каком-либо другом регистре на видеокарте указывается адрес в адресном пространстве видеокарты. для демонстрационных целей можно сказать, что вам было предоставлено окно размером 16 Мбайт на адрес x86 0x80000000. 16 Мбайт - 0x01000000. если вы хотите получить доступ к адресу 0x04321888 в видеопамяти, вы можете предположить, что вам нужно установить регистр сегмента на видеокарте в 0x04, а затем в адресном пространстве x86 (которое также является адресным пространством pci (e)) используйте адрес 0x80321888.
Нижняя строка здесь - взять несколько бит отсюда и несколько бит оттуда, собрать их вместе и это адрес в целевом объекте. Когда речь идет о периферийных устройствах, будь то видеокарта или контроллеры ввода-вывода на борту, или контроллер pci или pcie, вы должны научиться думать в терминах адресного пространства целей. процессор имеет адресное пространство с точки зрения ваших программ. Mmu может и может скремблировать это в физическое адресное пространство, тогда у вас есть адресное пространство вашего компьютера, а затем периферийные устройства, к которым осуществляется доступ через pcie, имеют собственное адресное пространство. То, что сделал мир intel и intel на базе ПК, делает физическое адресное пространство процессоров и адресное пространство pcie одинаковым. Виртуальное и физическое скремблирование в mmu все еще есть, и окно в периферийное адресное пространство все еще существует, вам все равно нужно взять немного адреса отсюда и немного оттуда, чтобы получить окончательный адрес в любой цели.
Реальный и защищенный относится к доступу. В C, например, вы можете создавать указатели, изменять указатели и создавать любой адрес, который вы хотите, не означает ли это, что вы можете ткнуть в другую память приложений или в память ядра? В идеале вы не хотите, чтобы это происходило так для каждого приложения, когда вы выполняете инструкции для этого приложения, вы находитесь в бит виртуальной машины, каждый доступ к памяти - это код или инструкция, проходящие через фильтр, если хотите. Этот фильтр проверяет, находится ли этот доступ в пределах допустимого пространства программ, если он выходит за пределы этого пространства, возникает исключение (думаю, прерывание), что исключение позволяет ядру (который не имеет этих ограничений или имеет разные ограничения), чтобы решить разрешить этот доступ, или, возможно, виртуализировать доступ к чему-либо или вызвать предупреждение пользователю (общая ошибка защиты). Возьмем, к примеру, настоящую программу виртуальной машины, например, vmware, чтобы виртуальная программа действительно выполняла инструкции на процессоре, когда эта виртуализованная программа обращается к тому, что она считает адресом для видеокарты, возникает ошибка защиты, драйвер vmware/applicaiton ( думаю, уровень ядра) принимает этот адрес и подталкивает ответ видеокарты и возвращает управление в приложение. Предоставление инструкций, выполняемых на металле, позволяет гораздо быстрее виртуализировать альтернативу, которая должна имитировать каждую инструкцию процессора. Это крайний случай, даже веб-браузер, который вы читаете на этом, был виртуализирован, так что он считает, что у него есть пространство памяти, которое основано на каком-то базовом адресе, таком как 0x000 или 0x8000, вы скомпилируете каждую программу для конкретной ОС к тому же плоская виртуальная память и операционная система заботится об изменении адресов от виртуального до физического. Доступ к вашим веб-браузерам по адресу 0x8000 может быть физическим 0x12345678, а ваш программный проигрыватель 0x8000 может быть физическим 0x2345678, но для обоих приложений их команды вычисляют 0x8000.
Спрашивать, что лучше всего, всегда относительный термин, один человек лучше всего другой худший. Вы должны определить лучшее из худшего для себя. Импульс и общественное мнение привели x86 в плоское пространство памяти или, по крайней мере, иллюзию плоского пространства памяти с точки зрения программистов, поэтому у вас будет меньше проблем с потоком.
Я рекомендую получить копию справочника по программированию и аппаратным средствам 8086/8088, который можно получить за несколько долларов.
http://www.amazon.com/Manual-Programmers-Hardware-Reference-240487-001/dp/1555120814/ref=sr_1_1?ie=UTF8&qid=1340000636& ср = 8-1 & ключевые слова = 8088 + программисты + задание
Возьмите симулятор, такой как pcemu (у меня есть клон для этой цели http://github.com/dwelch67/pcemu_samples) и играйте с набором команд, старой школой задолго до виртуализации, защиты и т.д. Назад, когда у вас были сегменты и смещения, вычисленные, как указано выше, сдвиньте сегмент влево четыре и добавьте смещение (которое описано в этом руководстве). Каждое поколение с тех пор что-то пыталось улучшить, пытаясь сделать обратную совместимость. Это, конечно, помогло прибыли, но превратило процессоры в злых зверей. Вам лучше забыть о деталях x86 и узнать о более чистых системах, поскольку из-за того, как развился x86, у вас будет минимальный выигрыш, например, попытка написать что-то в asm поверх скомпилированного кода. Поскольку процессоры из разных семейств выполняют один и тот же код на разных скоростях, часто новое поколение выполняет ручной настройку кода из предыдущего с гораздо меньшей скоростью. Вы не можете вручную настроить что-то быстро на всех платформах, не быстрее, чем компилятор, поэтому просто оставить xmm asm-код для компиляторов. Работайте на нормальных платформах, где у вас нет этих проблем, и можете настраиваться, если хотите, или сделать лучший компилятор и т.д.