![]() |
|
Модераторы: bsa |
![]()
|
|
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Здравствуйте, форумчане.
Да, я уже поднимал эту тему, но, по правде сказать, в тот раз на некоторые вопросы ответа я не получил и решил, что книга это исправит. Но нет, не исправила. Вот накопившиеся вопросы: 1) Как я уже усвоил из предыдущей темы, в Windows (а, может, во всех ОС?) есть виртуальная память. На протяжении всего времени exe-файл работает с ней. Но я слышал вопросы о том, что некоторые программисты в результате операции std::cout << &a в функции main видели у себя на экране разные цифры, а значит, переменные при разных запусках занимали разные позиции. А значит, что в коде не прописаны адреса переменных даже в их виртуальной памяти. Так каким же образом программа получает эти неслучайные адреса? 2) Как работает программа? Моя гипотеза: в ОЗУ заносится бинарник, а далее программа подгружает из него все функции и далее работает по бинарнику, пошагово выполняя инструкции, которые в нем записаны и переходя по нужным меткам. 3) Физическая память. Я прочитал, что из-за ее фрагментации если не будет подходящего по длине пустого фрагмента, то будет отказано в доступе к памяти. Это в корне противоречит тому, как я думал. Я считал, что если мы создаем в виртуальной памяти массив, то каждая из его ячеек может располагаться в абсолютно произвольном месте. Это не так? 4) Насколько я понимаю, объекты также могут быть автоматическими, как и другие переменные. Однако мой товарищ сказал мне, что объекты всегда хранятся в динамической памяти, даже когда мы этого явно не задаем. Кто из нас прав? 5) Когда использовать автоматические переменные, а когда - динамические? Из предыдущей темы я узнал, что автоматические переменные гораздо быстрее удаляются, а к динамическим гораздо быстрее доступ. Выходит, что если мы часто обращаемся к переменной, то ее надо объявить как динамическую, а если мы ее используем мало, то нам гораздо выгоднее, чтоб она быстро удалилась? И почему объекты надо всегда хранить в динамической памяти? 6) Я прочитал, что классы в памяти не хранятся, но как же тогда мы можем использовать их методы подобным образом: name::method() ? 7) Правда ли, что слова private, public и protected перед членом класса в коде никаких изменений не делают и служат только для логики? 8) Бывают статические, динамические и автоматические переменные. Бывают ли еще какие-то, которые отличаются от этих по сроку жизни? 9) Я слышал, что структура и класс - одинаковые вещи за исключением тех мелочей, что поля у структуры по умолчанию декларируются как public, а у класса - private. Так ли это? 10) Когда создается автоматическая переменная? В том месте, где программист ее объявил в коде или при входе в блок кода? 11) Блок кода ведь тоже помещается в стек? Т. е. когда программа доходит в функции до блока кода ({блок}), то она создает новую ячейку в стеке, которая характеризует этот блок? 12) Объектный код - это по большей части исполняемый код? А линкер, выходит, просто подставляет нужные адреса переменным, и все? Если так, то в теории один и тот же линкер может отлинковать объектный код, сгенерированый разными компиляторами! В wiki просто прочел вот это:
Уважаемые программисты! Простите за огромное количество вопросов! Буду очень благодарен тому, кто захочет помочь! Это сообщение отредактировал(а) Hagrael - 17.8.2011, 12:40 |
|||
|
||||
| boostcoder |
|
||||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
это в какой теме вас в этом убедили? пруф пожалуйста. не уверен, но помоему, разницы в доступе нет для переменных на стеке и переменных в куче.. а это откуда взято? я очень редко беру на себя ручное управление памятью. не нужно искушать вероятность возникновения утечки ;)
не нужно путать код и данные. не уверен что правильно понял вопрос...
а сам-то как думаешь? разве в ассемблере есть такие ключевые слова? ;) да. но только в с++. |
||||||
|
|||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
| Hagrael |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
boostcoder, спасибо за ответ!
Но тогда вообще зачем использовать динамические переменные?
Действительно, я сейчас сам понял, что вопрос ошибочен.
ОК ОК, почитаю, чем они отличаются в других языках. Добавлено через 1 минуту и 15 секунд mes, т. е. на самом деле место в виртуальной памяти у переменной всегда одно и то же? Даже когда речь идет о динамической памяти? |
||||||
|
|||||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
динамические, я крайне редко использую. обычно обернутые в shared_ptr. mes, а что нужно понять из вашего примера? адрес переменной i одинаковый в двух вызовах. но функция не статическая. и переменная не статическая. поэтому мне кажется это просто случайность, или линкер очень грамотно понял ситуацию. или что? |
|||
|
||||
| asmdzen |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 345 Регистрация: 28.11.2010 Репутация: 3 Всего: 5 |
так разве не так и должно быть, при вызове функции место для переменной выделяется в стеке, когда f() вызывается из g() в стеке присутствует уже и адрес возврата из g() в main(), вот только не понятно куда девались еще 12 байт, или это какие то push esp? |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ммм.. функция одна, стек один, если на стеке никого больше нет, то адрес автоматической переменной будет одним и тем же при каждом вызове.. а если есть то меняется, это и показывает пример.. |
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
mes, ну да.. понял.
|
|||
|
||||
| asmdzen |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 345 Регистрация: 28.11.2010 Репутация: 3 Всего: 5 |
||||
|
||||
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Так что, может одна и та же переменная в коде при различных обстоятельствах иметь разные адреса?
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
| rodnover |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
1, 2. Для загрузки файла в память используются первая часть файла exe (можно открыть в любом HEX редакторе и поковырять). На сайте wasm.ru, в принципе, есть много информации по структуре этого блока (PE-заголовок). В этом заголовке указаны базовый адрес программы, виртуальные адреса всех сегментов (кода, данных, стека) относительно базы и их размеры. На основе этих данных выполняется защита памяти (как, например, ошибки "память не может быть Read"). Да, забыл, в этом же заголовки прописываются все функции из внешних dll, подключенных статически. Во всей программе используются относительные адреса от базового адреса. Например, функция PrintMyStr() расположена на +0x100 байт от базового адреса. std::string my_str расположена +0x92 от базового адреса.
3. Управлением памятью осуществляют специальные менеджеры памяти, в задачи которых входит, выделение, освобождение страниц памяти, возможно, их дефрагментация и т.д... 4. Динамические объекты могут работать создаваться медленнее, в следствии каких-либо алгоритмов менеджера памяти, в то время, как на выделение объекта в стеке, фактически вызывают одну команду смещения указателя на верхушку стека. Но не думаю, что это замедление хоть сколько-то заметно. 5. Стек ограничен. В нем, помимо переменных хранится множество служебной информации (адреса возвратов из подпроцедур, блоки исключений). Наверно, всем встречалось сообщение об ошибке "Stack overflow" вызванное бесконечной рекурсией. Поэтому, в динамической памяти необходимо помещать крупные блоки информации. Это сообщение отредактировал(а) rodnover - 16.8.2011, 21:06 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
| rodnover |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
Ой да, конечно.
Я думаю, там намного больше описок и неточностей. ;) Это сообщение отредактировал(а) rodnover - 16.8.2011, 21:05 |
|||
|
||||
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Он поставляется вместе с ОС или это нечто еще более низкоуровневое? А как программа узнает, какой адрес стоит занять? Ей дает об этом знать менеджер памяти? Базовый адрес - это адрес в виртуальной памяти? Если все остальные адреса указаны относительно него, а сам базовый адрес указан в файле, то одна и та же переменная обязана каждый раз иметь тот же адрес (сам я понимаю, что это невозможно, но все идет к этому). Т. е. объекты могут быть автоматическими, да? |
|||
|
||||
| asmdzen |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 345 Регистрация: 28.11.2010 Репутация: 3 Всего: 5 |
||||
|
||||
| rodnover |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
С ОС по умолчанию, но знаю, что билдер и делфи свой менеджер памяти используют.
Базовый адрес (получается виртуальный, обычно указывается 0x400000. С количеством нулей могу напутать) программы указывается в PE-заголовке. Какой там указан - с такого и будет грузится. То есть, базовый адрес - это просто значение, которое выбирается самой программой и от которой она начинает плясать.
Динамически созданные переменные могут распологаться в разных адресах кучи (int *c пример указателя на кучу). Что в вашем понимании "автоматические переменные"? Это сообщение отредактировал(а) rodnover - 16.8.2011, 21:16 |
|||
|
||||
| Hagrael |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Автоматическая переменная - это переменная, которая располагается в стеке блока и удаляется при выходе из него. Это неправильное определение?
Ясно.
Кто из вас прав? Натолкнулся на 2 новых вопроса:
Надеюсь, понятно изъяснился. Это сообщение отредактировал(а) Hagrael - 16.8.2011, 21:24 |
||||||
|
|||||||
| rodnover |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
Я просто не встречался с таким определением.
Я вот что имел ввиду. Физический адрес, то будет разным, вот только есть ли простой способ получить его из программы? http://www.wasm.ru/article.php?article=vgw03 База образа:
10. Тут, вообще, много зависит от компилятора и параметров оптимизации. Например, при некоторых параметрах оптимизации одни и те же ячейки памяти будут использоваться для разных переменных. 11. Код распологается в сегменте кода (это отдельный сегмент), а в стек помещается адрес возврата из функции (попробуйте поизучать ассемблер). Вот первая ссылка из гугла http://www.insidepro.com/kk/144r.shtml Это сообщение отредактировал(а) rodnover - 17.8.2011, 06:47 |
||||||
|
|||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
грубо: у объекта(переменной) есть время жизни.. на это время он (и только он) занимает определенные ячейки памяти.. http://liveworkspace.org/code/a0a9ebcea644...dcb7012796df81b Добавлено @ 08:20 пример показывает, что в разные промежутки времени на одном адресе расположены разные объекты.. функция/блок кода знает смещение в стеке до нужной переменной, и поэтому ей не важно реальный адрес переменной.. Это сообщение отредактировал(а) mes - 17.8.2011, 08:21 |
|||
|
||||
| rodnover |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
http://liveworkspace.org/code/e7691f4dd47c...8fa6e8b898da032
Вот я про такой пример имел ввиду. При некоторых опциях компилятора адрес будет одинаковым. P.S. Сайт отличный. Вообще в восторге. |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
вообще то в том примере он для всех тех переменных всегда будет одинаков Добавлено @ 08:32
кажется я понял, что тс непонятно и чего мы упустили.. Hagrael, почитайте про регистры процессора, именно через них он узнает какой кусок кода выполнять и где начало данных конкретного блока/функций.. Это сообщение отредактировал(а) mes - 17.8.2011, 08:33 |
||||
|
|||||
| rodnover |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
В примере из моего сообщения на сайте адреса неодинаковы. ;) Но при некоторых опциях будут одинаковы.
Вот заставили человека ассемблер изучать, но мысль верная и полезная. |
||||
|
|||||
| Hagrael |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Классная статья, rodnover! Правда описывает она мало, и после ее прочтения появилась уйма вопросов
Думаю, вначале следует разобраться только со структурой самого exe-файла, не же ли сразу переходить к заголовку. Буду читать.
Т. е. в стандарте не сказано, когда переменная должна создаваться - при входе в блок кода или же в том месте, где она создается в коде? Вот я и думаю его поучить. Но у меня сейчас не так много времени. Хотя действительно надо бы постараться. Я почитаю про стеки вызовов функций. Как я понял, автоматические переменные - это то же самое, что и локальные?
Так "Да" или "Нет"? Появился новый вопрос: Спасибо за помощь! |
||||
|
|||||
| asmdzen |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 345 Регистрация: 28.11.2010 Репутация: 3 Всего: 5 |
а Вы перезапустите пример mes'а и посмотрите как меняется адрес переменной. т.е. насколько я помню в заголовке PE указывается адрес куда программа хотела бы загрузится, а потом система уже сама определяет может она ее туда загрузить или нет.
да, но когда эта память выделяется для него, ведь IMHO писать все переменные в начале функции или по мере необходимости уже в коде - дает примерно тот же результат, т.е. место в стеке для всех переменных выделяется при входе в функцию, разница только в том что конструкторы будут вызываться уже там где объект был объявлен. |
|||
|
||||
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Многие говорят: "Размер переменной зависит от платформы. Точных данных нет" etc. А от чьей платформы? Платформы разработки программы или же платформы пользователя? Как я понимаю, второе. Тогда, выходит, что всеми размерами переменных управляет Windows?
Добавлено через 2 минуты и 13 секунд Ответ получен! |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Хм. У меня тут в голове промелькнуло в голове: "А зачем вообще в файле указывается базовый адрес, если Windows его очень навряд ли даст? (а вообще, Windows на него внимание обращает?) И чем этот базовый адрес будет лучше того, что даст Windows?" |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
для стековых переменных память не выделяется вообще (она выделенна изначально для всего стека) .. Добавлено @ 09:13
затем , что если загрузчик хочет загрузить по другому адресу, он должен подправить связи.. Это сообщение отредактировал(а) mes - 17.8.2011, 09:13 |
|||
|
||||
| rodnover |
|
||||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
В контексте получается - да, тоже самое.
Опять таки, в конексте - могут.
Windows, Linux, MacOS, тип процессора (16, 32, 64 битный) и так далее.
Если компилятор определяет, что переменная больше не используется, то он может начать в этой ячейке хранить другую переменную.
Сколько раз я проверял под отладчиком винда всегда выдавала мне тот адрес который указан в PE-заголовке. А вообще это просто точка отсчёта, для ориентации по памяти программы все смещения в программе (jmp, jz, jnz, call) указаны относительные. Некоторые защиты строятся на изменении этого адреса. 12. В принципе да, если у него будет одинаковый формат и одинаковые соглашения. Это сообщение отредактировал(а) rodnover - 17.8.2011, 09:16 |
||||||||||
|
|||||||||||
| asmdzen |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 345 Регистрация: 28.11.2010 Репутация: 3 Всего: 5 |
я имел ввиду смещается указатель на вершину стека, Вы меня поняли ) вообще то дает ) писали уже что есть оптимизация для этого, т.е. если программа загрузится куда хотела то будет работать "быстрей" |
|||
|
||||
| rodnover |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
+ еще протекторы - добавляют свой сегмент, кодируют (сжимают) программу и указывают свой адрес входа. А при запуске распаковывают программу "где она и была" и передают управление ей. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ох как скользко.. с точки зрения асм кода, да, может, также может и не занимать памяти вообще.. но это все оптимизация конечного кода.. но.. хотелось бы взглянуть на компилятор, на котором средставами языка, можно получить один и тот же адрес для разных переменных одного блока.. |
|||
|
||||
| rodnover |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
union никто не отменял.
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
а не разных переменных одной специальной структуры.. |
|||
|
||||
| Hagrael |
|
||||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Вопрос почти решен. Только вот этого я не понял: Буду признателен, если объясните.
Ответ получен
И для каждой из ОС свой метод компиляции, так? |
||||||||
|
|||||||||
| rodnover |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
Вот на вскидку вспомнил
http://www.aspack.com/asprotect.html В целом, это инструментарий, который сжимает, шифрует код программы (типа sfx архива) и при каждом запуске воссоздает оригинал программы, который и работает. Вот еще: http://ru.wikipedia.org/wiki/ASProtect
Метод то один, только условности разные. Например, в 32битных системах размер указателя 4 байта, в 64 битных - 8 байт, вызов внешних процедур, использование стека, регистров при вызове внешних процедур. Это тоже всё ассемблером успешно познается.
Потому я смайл и поставил. Хотя, структура то для экономии памяти и была придумана. Вообще, не вижу причин, чтобы преднамеренно указывать 2м переменным один адрес. Это сообщение отредактировал(а) rodnover - 17.8.2011, 09:49 |
||||
|
|||||
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Фрагментация памяти? Насчет протектора: он извлекает программу из архива и кладет в какую-то директорию как .tmp-файл, после чего запускает? А размеры задаются при компиляции или же при запуске программы сообщаются ей с помощью ОС? |
|||
|
||||
| rodnover |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
Да не. Смысл экономить на том чего много?
При компиляции задаются. В простом случае компилятор создается под конкретную платформу. Но, также есть кросскомпиляторы (которых всё больше), в параметрах которых можно указать платформу, формат выходного файла, на основании которого они будут компилировать. Пример
cpu-type указывает под какой процессор компилировать. Это сообщение отредактировал(а) rodnover - 17.8.2011, 10:15 |
||||||
|
|||||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ну да именно для экономии памяти |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
|
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
Компилятор может поместить 2 разные переменные из одного блока в одно и то же место в памяти, если у них не пересекаются времена жизни (live range analysis). Но как только вы возьмете у переменной адрес, ее область жизни немедленно расширится до области жизни переменной с этим самым адресом (как минимум), а после этого у оригинальных переменных их области жизни пересекуться, и компилятор разведет их по разным адресам в памяти. Так что поместить 2 разных переменных по одному и тому же адресу компилятор теоритически может, а вот увидеть это средствами языка увы нельзя. |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
и пока мы не взяли адрес (пусть косвено, посредством передачи объекта по ссылке) некорректно говорить о том, что объект располагается по какому либо определенному адресу... хм .. что то мне это вдруг странным образом напомнило одного знаменитого кота.. раньше как то внимание не заострялось на этом Это сообщение отредактировал(а) mes - 17.8.2011, 13:09 |
||||
|
|||||
| rodnover |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
Оптимизация Кота?
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Кот Шрёдингера
|
|||
|
||||
| boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
|
|||
|
||||
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Т. е. протектор загружается загрузчиком программ, проделывает нужные операции... А дальше что? Программа-то должна загрузиться загрузчиком программ, чтобы тот сделал все нужные выводы, сообщил о чем надо Windows etc.
|
|||
|
||||
| rodnover |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
типа такого:
оригинальная программа
Загрузчик делает обертку над программой, пакует, кодирует и получается такой псевдокод:
Грубо, конечно, но примерно так. |
||||
|
|||||
| maydjin |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 25.1.2010 Репутация: нет Всего: нет |
Не совсем верно, а про оптимизацию совсем не верно. Базовый адрес записываеться компоновщиком на этапе сборки программы, и может быть изменен соответсвующими опциями оного. На самом деле это не совсем адрес - это смещение относительно начала виртуально адресного пространства, которое у каждого процесса своё. Не знаю точно как всё дело происходит под linux и другие платформы (хотя думаю существенных отличий нет), а под win это выглядит примерно так: 1. Загрузчик получает уведомление о запуске нового процесса 2. Загрузчик вызывает менеджер памяти, который выделяет под x32 2^32 под x64 2^64 байт виртуальной памяти процессу(за предоставление этой памяти отвечае страничный мененджер). Процессу по умолчанию доступна только половина адресного пространства, доступ к второй половине вызовет ошибку, т.к она доступна только ядру. 3. Загрузчик считывает pe заголовок и размещает в виртуальном адресном пространстве код и статические данные. 4. Ядро создает основной поток процесса выделяя память под стек относительно адреса базы, при том на сколько я помню начало стека будет как раз этим самым базовым адресом.(Тут не совсем уверен - нет под рукой отладчика если базовый адресс не адрес начала стека, то это адрес первой инструкции кода основного потока) 5. Управление передаеться программе Подробней почитать/спросить можно на вышеупомянутом сайте wasm.ru. Не совсем уверен за п4 но если посмотреть адреса локальных переменных в основном потоке то похоже на правду. Главный мессадж моего топика : Да программа всегда загружаеться по базовому адресу. Но этот адрес расположенн в виртуальном адресном пространстве, т.е физический адрес на 99,9999......% будет каждый раз новый(ну по крайней мере примерно первые <количество dword в вашей оперативной памяти> запуска под win32 Прошу прощения если есть какие нибудь неточности, но основную мысль надеюсь передал верно. Это сообщение отредактировал(а) maydjin - 17.8.2011, 21:06 |
|||
|
||||
| rodnover |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
по пункту 4му - точно не верхушку стека указывает. Адреса и размеры сегментов ниже прописываются.
|
|||
|
||||
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Спасибо за ответы, но сейчас я пытаюсь разобраться со стеками. И, признаться, не могу перевести некоторые фрагменты:
О каких распечатанных кружках-досках идет речь? о_О Добавлено через 54 секунды (да-да, это не информация о стеке, но изучая стеки, я вдруг обнаружил, что не понимаю термин ЦПУ). |
|||
|
||||
| rodnover |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
Если я не ошибаюсь, то printed circuit boards переводится как печатная плата.
|
|||
|
||||
| fish9370 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 15.4.2007 Где: Москва Репутация: 1 Всего: 1 |
Hagrael, позволь дать совет, во-первых тебе нужно изучать линукс.. вижу твою тягу к системному программированию (или по крайней мере к изучению работы ОС) - линукс для этого подходит как нельзя лучше.. он открыт, под него довольно просто писать свои драйверы, есть и документация, и куча примеров.. во-вторых начни с книги "Разработка ядра Linux" (Роберт Лав).. ее можно купить или скачать в сети.. - очень простым языком описанно как работает ОС из каких подсистем она состоит и т.д.. там есть и сравнение винды и линукса, так что это тебе будет в любом случае интересно..
целенаправленно сядь и прочитай книжку.. -------------------- undefined |
|||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Приблизительный перевод: Центральный процессор (CPU), это часть компьютерной системы который обеспечивает выполнение инструкций компьютерной программы. Выполняет основные арифметические, логические операции и операции ввода/вывода. Процессор по сути - мозг компьютера. Термин существует в компютерной индустрии как минимум с начала 60-х годов. Хотя форма, схема и реализация ЦПУ значительно изменились по сравнению с первыми образцами, его основные предназанчение остается таким-же. На больших машинах процессоры занимают одну или несколько печатных плат. |
|||
|
||||
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
volatile, спасибо за дословный перевод. Не стоило, серьезно
rodnover, спасибо за ответ. fish9370, м-м, не знал этой информации о Linux-e. Спасибо. Пост благодарностей Это сообщение отредактировал(а) Hagrael - 19.8.2011, 15:24 |
|||
|
||||
| Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Я приостанавливаю эту тему... снова. Вначале изучу микроконтроллеры, а потом буду читать про архитектуру компьютера. Всем спасибо!
|
|||
|
||||
| bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: нет Всего: 88 |
для экзешника скорее всего именно енго и даст, потому что на момент его загрузки виртуальная память процесса практически пуста (экзешник загружается туда почти первым). А вот с длл да, тут как повезет
-------------------- Обижено школьников: 8 |
|||
|
||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |