- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
...
ASSERT( sizeof(L"SystemPartition") <= sizeof(nameBuffer) );
/* Китайский код? Или по другому нельзя было запихнуть строку в ентот массив? */
nameBuffer[0] = L'S';
nameBuffer[1] = L'y';
nameBuffer[2] = L's';
nameBuffer[3] = L't';
nameBuffer[4] = L'e';
nameBuffer[5] = L'm';
nameBuffer[6] = L'P';
nameBuffer[7] = L'a';
nameBuffer[8] = L'r';
nameBuffer[9] = L't';
nameBuffer[10] = L'i';
nameBuffer[11] = L't';
nameBuffer[12] = L'i';
nameBuffer[13] = L'o';
nameBuffer[14] = L'n';
nameBuffer[15] = L'\0';
nameString.MaximumLength = sizeof(L"SystemPartition");
nameString.Length = sizeof(L"SystemPartition") - sizeof(WCHAR);
status = NtSetValueKey(setupHandle,
&nameString,
TITLE_INDEX_VALUE,
REG_SZ,
volumeNameString.Buffer,
volumeNameString.Length + sizeof(WCHAR)
);
...
Чем это может обусливливаться?
я ядрах осей, в коде который относится к инициализации и бутстрапу, можно всякого интересного найти.
Обычно часть стандартной библиотеки си и обычно линкуется статически. Так что скорее всего это исключено.
это в прикладухе у тебя и сегмент данных всегда под рукой, и стек на пример почти безразмерный. потому что их ОС для тебя загрузила и проинициализировала.
а кто их по твоему для ОС загрузит и/или проинициализирует?
Вот разве что не загружена страница, в которой лежал бы литерал L"SystemPartition"... но это же обычно сегмент кода?
нет. литералы лежат в BSS.
> Вот разве что не загружена страница
нет. кернела грузятся бутстрапом как правило в одну большую страницу. виртуальной памяти на ранней фазе инициализации еще нету.
> Так что большинство подсистем уже запущено...
не знаю - системщина под виндами это не моя область. ну да ни в одном из моих комментарием я и не отрицал что код может быть говном.
народ спрашивал для чего такое может быть. то сверху - есть один из способов зашить в код строковый литерал, для того что бы он в сегменте данных не появился. и в системщене есть на самом деле места где это нужно.
Не путать сегмент в оперативке и секцию в exe-файле.
но как правило, сегменты в ехе-шнике маппятся прямо в память, как отдельные сегменты. и по типу сегмента в ехе-шнике, сегменту в памяти выдаются соответствующие аттрибуты: исполняемый/рид-онли, рид-онли, рид-врайт. в виндах в оссобенности это используется для шаред сегментов.
для простых ехе-шников, сегменты буквально мапятся. и загружаются при первом доступе, как если бы из свапа. (для ускорения запуска, предзагрузка может заранее что-то подгрузить.)
в случае кернела, сегменты скорее всего будут замержены и как один в память залиты (кернел в одну (большую) страницу слегка повышает производительность). в случае драйвера, как правило кернел уже загружает посегментно, но загружает сразу все полностью, потому что драйверам виртуальная память в общем случае недоступна.
в виндах оно может быть и не так, но и сильно отличатся не будет.
Некоторые отдельные секции могут попадать в один сегмент. Собственно в системах с линейной памятью, например 32х винда в обычном режиме, адресное пространство - это в основном отдельный общий большой сегмент.
cs - сегмент кода на все доступное пространство, RX
ds, es, gs - сегмент данных на все доступное пространство, RW
fs - сегмент с инфой о процессе, RW
Т.е. сегментные регистры настроены на отъебись, а все разруливается уже на уровне страниц.
Именно.
ты немножко путаешься.
flat memory это как бы стандартная фича. виртуально адресное пространстно это самый верхний уровень подразделения виртуальной памяти.
дальше идут сегменты, которые в нынешнее время не имеют отношения к старым 64К сегментам 8086. сегмент это просто кусок непрерывной виртуальной памяти, который часто описывается одним дескриптором в таблице виртуальной памяти процессора. (вот сюда как раз и мапятся сегменты ехе-шника).
самый нижный уроветь - это непосредственно страницы виртуальной памяти.
это конечно не совсем уровни: сегменты виртуальной памяти и страницы виртуальной памяти ортогональны. сегменты говорят процу какая часть виртуальной памяти может аддресоватся (все что не описано - адресоваться программой не может). страницы нужны для сваппинга или динамической загрузки данных осью.
> Некоторые отдельные секции могут попадать в один сегмент.
Да. Сегменты с аналогичными свойствами как правило сливаются вместе. Потому что количество сегментов влияет на скорость переключения процессов: больше сегментов/дескрипторов, дольше длится переключение процессора на виртуальную память нового процесса. (Хотя вроде на последних Интелах есть какие-то хаки что бы этого избежать.)
Нет. Рассмотрим этапы трансляции адреса на 32 битной архитектуре intel:
1) Адрес, указанный в команде складывается с адресом начала сегмента, прописанным в дескрипторе, на который ссылается сегментный регистр указанный (или подразумевающийся) в команде. Здесь же проверяется выход адреса за границу сегмента. В итоге мы получаем виртуальный адрес.
2) Виртуальный адрес транслируется в физический по дереву таблиц трансляции. Проверяются права на доступ к странице.
Т.е. мы имеем такой порядок - сегмент:адрес -> виртуальный адрес -> физический адрес.
Так вот. Во flat модели дескрипторы сегментов настраиваются так, что адреса транслируются в виртуальные без изменений. (Ну за исключением сегмента, на который ссылается регистр fs в windows, который для удобства ссылается на структуру с инфой о процессе). Сегменты применяются только для ограничения доступной пользовательской программе области (например в 32хбитных осях это младшие 2-3 гигабайта).
Секции экзешников никакого отношения к сегментам не имеют. Ось размещает секции в памяти, следуя советам компилятора, и расставляет на страницы, в которые попали эти секции, соответствующие атрибуты (RW для данных и стека, RX для кода, RWS для шаренных секций и т.п.). Секции с аналогичными атрибутами компилятор объединяет прежде всего для экономии памяти (не сегментных дескрипторов которых от силы штук 5!).
LOL. транслируются из чего?? :))))
> Ось размещает секции в памяти, следуя советам компилятора
Сегменты в ехе-шнике и есть не что иное как "советы компилятора." Или более точнее - советы линкера.
N.B. Ты похоже недооцениваешь роль линкера во всем этом. Выше ты вполне вероятно имел ввиду не "транлируются" а "релоцируются."
Спорить не буду. Похоже что терминология на виндах отличается. Хотя как бы сильно ты мне и не противоречишь.
> LOL. транслируются из чего?? :))))
Из адреса который указан в команде.
> Выше ты вполне вероятно имел ввиду не "транлируются" а "релоцируются."
Нет, именно транслируются процом.
Релокации может и не быть, если операционке удалось замапить все секции по предложенным линкером адресам.
Сегментные дескрипторы и регистры используются ими только для создания плоского адресного пространства.
Все атрибуты секций\сегментов, которые линкер указал в экзешнике применяются на уровне страниц и только страниц.
Чтобы не быть голословным приведу пару ссылок - http://www.ibm.com/developerworks/ru/library/l-memmod/ ну и допустим вот http://itechspace.wordpress.com/2008/08/19/windows-memory-model/.
но я как бы здесь пытался в абстрактных понятиях (не вдаваясь в нерелевантные тех подробности) объяснить разницу между тем как видит память процесс и как ее видит система на фазе бутстрапа. смотри оригинальный топик.
> не связывают сегменты\секции в исполняемом файле с сегментными регистрами и дескрипторами сегментов.
сегодня - нет. ранние винды и линухи до 2.4 - связывали. потому что именно как бы для этой цели Интел и ввел эти дескрипторы. то что в конце от них пришлось отзаться (в линухе начиная с 2.5), это другая песня.
то что я подразумевал под "сегментом" или "дескриптором" в линухе называется VMA (Virtual Memory Area; они в старые времена на i386, как и рекомендовалось в прошлом Интелом, мапились на дескрипторы). и это то что ты видишь под линохом в /proc/$$/maps или под виндой в VMMap ( http://technet.microsoft.com/en-us/sysinternals/dd535533.aspx )
> Все атрибуты секций\сегментов, которые линкер указал в экзешнике применяются на уровне страниц и только страниц.
За исключением конечно атрибута "шаред" который и живет как раз только на уровне OC в VMA. :)
Ну да, согласен, я просто рассуждал о более-менее современных системах с flat memory model.
> то что я подразумевал под "сегментом" или "дескриптором" в линухе называется VMA
Ок, теперь все встало на свои места :)
что?
Сегментные регистры в 32хитный ОС почти всегда указывают на нули. Смысл сегмента только в отделении колец защиты, а сегментация осталась в шестнадцатибитных ос
Это единственное, что я вспомнил из исключений. CS, DS, ES, SS обычно с нулевой базой (хотя значения дескрипторов могут быть разными).
В длинном режиме 64-битного процессора у инструкций нельзя использовать префиксы CS:, DS:, ES:, SS:, потому что всегда используется дефолтный префикс, а вот FS: и GS: использовать можно (этим и пользуется Винда, пихая туда указатель на TIB).
Не только. При помощи флагов «DB» и «L» дескриптора сегмента происходит переключение «на лету» между 16-битным, 32-битным и длинным 64-битным режимами; так функционирует выполнение 32-битного кода в 64-битных ОС, например.
https://govnokod.ru/25776#comment497735
давай про пхп
Да, давай про пхп. Дмитрий Стогов протащил в PHP 7 очереди, стеки, деки, множества и другие структуры данных:
https://www.php.net/manual/ru/book.ds.php
(только непправильные ответы)
>деки
а функцию бесселя?
зы: посмотрел ссылку и понял, что бандерлоги обезьянничают вечно ненавидимую ими джаву, потому что для плюсов у них интеллект не дотягивает.
ПХПшники часто садились кружками, чесались, отыскивали блох и притворялись программистами
https://github.com/otya128/winevdm
Переключение из long mode в «короткий» слишком дорогое, чтобы его использовать в многозадачной среде.
А разве в нём что-то менялось?
Я помню, что в 2.5 перевернули набор дефолтных драйверов, кучу говна зашили прямо в ядро, и его теперь не нужно инсталлировать через insmod.
В общем случае, код не работающий на высоких IRQL вполне свопуется (т.к. несвопуемая память дорогой ресурс).
Там же где и винду.