5 / 5 / 1
Регистрация: 20.11.2017
Сообщений: 51
1

Адресация переменных и всей структуры программы на реальной памяти в ОС

20.11.2017, 21:38. Показов 2616. Ответов 42
Метки нет (Все метки)

Доброго времени суток, Вопрос по памяти, не совсем понятно:
1. Я написал программу 1.cpp, выполняю ее компиляцию, если я не использую динамическое выделение памяти, то при ее компиляции, исходя из объявленных переменных и еще чего-то там(?????), вычисляется объем памяти, требуемый для выполнения программы, затем происходит линковка - компоновка написанной программы, адресация каждой инструкции и разрешение имен для ф-ций(их адресация) . Линкер делает адресацию относительно "нуля" всего блока инструкций. Таким образом получается исполняемый файл - блок инструкций с рассчитанным, для его выполнения, объемом данных, у которого каждая инструкция теперь имеет адрес и за именем ф-ции скрывается адрес.

2. При запуске такого файла, ОС выделяет память, рассчитанную при компиляции и загружает программу в какую-то область оперативки с адресом X, где X и является по-сути тем самым "нулем" программы. ОС настраивает процессор на выполнение 1-ой инструкции и начинается ее выполнение, как только он доходит до инстр. вызова ф-ции, он кладет в IP адрес след.инструкции (в стек?) и переходит по адресу, который был дан ф-ции при линковке, передавая пар-ры этой ф-ции в стек обл-ти памяти где лежит наша программа. (Как этот стек выделяется? Это часть памяти, рассчитанной при компиляции? ) , затем ф-ция выполняется, работая с лок. переменными, которые лежат в том же стеке, и дойдя до return из стека (IP???) выдергивается адрес возврата и "процессор возвращается с каким - то значением".

3. При использовании динамического выделения, у нас и статическая память будет иметь место, в которой будет храниться выполняемая программа? и в процессе выполнения программы, дойдя до инструкции malloc (new), происходит выделение дин.памяти "где-то" в опер. памяти.
Верно ли я понимаю, скорректируйте, пожалуйста))))

Хочу понять и иметь общее представление о данном процессе) Буду очень рад, если кто-нибудь возьмется написать поэтапно все это)))
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
2
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.11.2017, 21:38
Ответы с готовыми решениями:

GlobalAlloc и адресация структуры
Привет всем! У меня небольшой вопрос по-поводу программирования на TASM (думаю он также...

Адресация переменных по стандарту МЭК 61131-3
Добрый день. Столкнулся с проблемой. Есть среда AXEl Logiclab по стандарту (МЭК 61131-3), есть...

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

Адресация переменных: найти и исправить ошибку в коде
Приветствую. Есть код: #include "stdafx.h" #include <iostream> using namespace std; int...

42
2756 / 1910 / 569
Регистрация: 05.06.2014
Сообщений: 5,560
20.11.2017, 22:06 2
1) Компилятор делает шмат кода рассчитанный на загрузку с некого базового адреса.
2) ОС выделяет под вышеназванный шмат адресное пространство и связывает его с exe-файлом. Дальше шмат загружается по ровно тем же механизмам, что и данные из свопа. Просто считайте что ваш exe присоединили к своп-файлу. Колдунство это называется "отображение файла в память", за подробностями - в Гугл.
2.1) Если базовый адрес уже занят, шмат приходится налету немного перепилить. В этом случае фокус с "прилепили exe к свопу" не работает - в памяти одно, в exe другое.
3) ОС выделяет фиксированный шмат адресного пространства под стек. Все локальные переменные тривиальных типов (у нетривиальных типа std::string может быть часть там, часть сям) и адреса возврата валятся туда. В принципе размер шмата можно настроить при компиляции, но если не настроили - будет взят по умолчанию. Можете считать что минимум мегабайт там точно будет. А если вдруг нужно больше - лучше задайте размер явно.
4) Динамическая память - к загрузке кода и стеку никакого отношения не имеет. Да, "где-то" выделяется, "куда-то" возвращается. ОС вполне возможно ничего про это возвращение не знает. Она манипулирует относительно крупными кусками данных (скажем, 64 кило), вы работаете с кусками помельче. Так что ленивый автор free мог сказать "у меня тут мелкие обрывки по килобайту, когда там они в кусок на 64 кило сложатся. Просто помечу память свободной, а на возвращение ее ОС забью".
3
5 / 5 / 1
Регистрация: 20.11.2017
Сообщений: 51
20.11.2017, 23:20  [ТС] 3
1.
Цитата Сообщение от Renji Посмотреть сообщение
1) Компилятор делает шмат кода рассчитанный на загрузку с некого базового адреса.
т.е. на этапе компиляции система уже предоставляет свободный адрес необходимой обл-ти памяти ? Если он не задан явно. Ф-ция Shmat() После чего при линковке относительно этого адреса выполняется адресация всех инструкций.

2 .
Цитата Сообщение от Renji Посмотреть сообщение
ОС выделяет под вышеназванный шмат адресное пространство и связывает его с exe-файлом
это при запуске exe? или тоже при компиляции?
Цитата Сообщение от Renji Посмотреть сообщение
3) ОС выделяет фиксированный шмат адресного пространства под стек.
Цитата Сообщение от Renji Посмотреть сообщение
3) ОС выделяет фиксированный шмат адресного пространства под стек
при запуске exe?
0
174 / 134 / 105
Регистрация: 14.04.2016
Сообщений: 719
20.11.2017, 23:29 4
Цитата Сообщение от prado777 Посмотреть сообщение
при запуске exe
Нет при компиляции! Поэтому ваш exe можно перенести на другой ПК.
1
2756 / 1910 / 569
Регистрация: 05.06.2014
Сообщений: 5,560
20.11.2017, 23:33 5
Цитата Сообщение от prado777 Посмотреть сообщение
т.е. на этапе компиляции система уже предоставляет свободный адрес необходимой обл-ти памяти ?
Система предоставляет персональное адресное пространство (один и тот же адрес в программе А и программе Б указывает на разные области памяти). Одна, заранее известная часть этого пространства зарезервирована под нужды системы. Остальная пуста и хоть на голове там ходи. Что в общем случае позволяет грузить программу по фиксированному (в персональном адресном пространстве) адресу. В некоторых частных случаях (DLL грузится в чужой процесс, где часть места уже застолбили) так красиво не выходит и нужно налету переправлять адреса в коде (сдвинем код на мегабайт, ко всем адресам приплюсуем тот же мегабайт. Где лежат "все адреса" известно из спец-таблички).
Цитата Сообщение от prado777 Посмотреть сообщение
при запуске exe?
Стек - при запуске. Где находится - хранится в спец-регистре (ESP).
0
5 / 5 / 1
Регистрация: 20.11.2017
Сообщений: 51
21.11.2017, 00:07  [ТС] 6
т.е. при компиляции:
Система предоставляет персональное адресное пространство.
а при запуске это АП связывается с ехе. Но при переносе еxe на др машину какое АП используется для связи с exe, если предоставление АП идет в процессе компиляции, не понятно.
0
2756 / 1910 / 569
Регистрация: 05.06.2014
Сообщений: 5,560
21.11.2017, 00:27 7
Цитата Сообщение от prado777 Посмотреть сообщение
т.е. при компиляции:
Система предоставляет персональное адресное пространство.
При компиляции выбирается базовый адрес в адресном пространстве. При запуске система выделит адресное пространство и застолбит этот самый базовый адрес за программой. Или не застолбит, если по каким-то причинам он уже занят.

Для понятности откатимся на адресацию реального режима (безнадежно устарело, зато просто и понятно). Любой адрес состоит из пары сегмент:смещение от начала сегмента. Все смещения известны на стадии компиляции. А сегмент определяется системой и кладется в специальный регистр. Далее когда программе нужно вызвать какую ни будь функцию, она говорит процессору "перейди по адресу сегмент по умолчанию:0x1234". Что это за сегмент по умолчанию такой - процессору виднее.

Теперь современная плоская модель памяти. Грубо и на пальцах - у каждой программы свой собственный сегмент на четыре гигабайта и лезть в сегмент соседа нельзя. Так как доступен всего один сегмент, про слово "сегмент" забываем, пользуемся только смещением (которое в личном сегменте может быть любым). Понятное дело, четыре гигабайта физической памяти программе никто не выделяет, большая часть ее сегмента не доступна ни для чтения, ни для записи. Делается это с помощью особого колдунства известного как "виртуальная память". Но чисто на бумаге - у программы четыре гигабайта адресов (адресное пространство), которыми она может распоряжаться как хочет.
1
5 / 5 / 1
Регистрация: 20.11.2017
Сообщений: 51
21.11.2017, 16:21  [ТС] 8
Renji.
1. При компиляции, точнее линковке выполняется расчет смещений каждой инструкции и ф-ций относительно базового адреса в программе (исходя из чего он назначается?). В результате в ехе файлике уже зашиты эти самые смещения. При запуске ехе система выделяет АП с каким-то уже физическим адресом, относительно этого физического адреса и происходит смещение, в результате процессор знает адреса инструкций в памяти. И эта память связывается с exe. Поэтому при переносе exe трудностей не возникает, так как имеются только смещения относительно какого-то адреса, который выделит система при запуске программы. Так?

1.1 Объем требуемого АП, рассчитанный на этапе компиляции, влияет на размер выделяемого АП или как вы написали "сегмент на 4 гига" и сколько там компилятор насчитал - это не важно, кусок все равно выделится одного размера??

2. Про стек. АП стека, которое выделяется при запуске exe, это часть АП, выделяемого системой для инструкций программы или это отдельное АП где-то там в памяти?
2.1 Когда процессор "шагает по адресам" и выполняет инструкции программы, он доходит до ВЫЗОВА (CALL) ф-ции, затем он делает push адреса точки возврата (IP), локальных переменных ф-ции в наш стек, затем делает jmp на адрес ф-ции, работает там с лок. переменными, делая pop из стека, и дойдя до возврата (RET) делает pop адреса возврата и возвращается в исх.место. А вот возвращаемое значение из ф-ции так же помещается в стек при выполнении RET и затем уже при возврате делается pop возвращаемого значения из стека? Так?
2.2 При передаче ф-ции аргументов (их копий), эти значения помещаются в стек. Мы с этими значениями в ф-ции поработали, стек очистился и после возврата, у нас эти переменные из АП программы, остались без изменения, если мы имеем дело с ссылками, тогда в качестве аргумента передается адрес в стек, так вот этот адрес на переменную, которая хранится в АП для нашей программы????? мы в теле ф-ции фактически работаем не с копией из стека, а уже со значением из АП для нашей программы делая для этого pop адреса ?????

3. Вызов ф-ции
Цитата Сообщение от Renji Посмотреть сообщение
А сегмент определяется системой и кладется в специальный регистр. Далее когда программе нужно вызвать какую ни будь функцию, она говорит процессору "перейди по адресу сегмент по умолчанию:0x1234"
Он добавляет смещение, которое соответствует ф-ции к этому 0x123 и переходит на получившийся адрес. Так?

3. Выделяемый кусок памяти АП при выполнении exe - это ведь статическая память?

4. Динамическая память. При ее использовании выделяется где-то память, у нас имеется указатель, содержащий ее адрес, и мы работаем с этой памятью через этот адрес. А работаем мы из того же нашего выделенного адресного пространства программы. Так?
0
2756 / 1910 / 569
Регистрация: 05.06.2014
Сообщений: 5,560
21.11.2017, 17:04 9
Цитата Сообщение от prado777 Посмотреть сообщение
1. При компиляции, точнее линковке выполняется расчет смещений каждой инструкции и ф-ций относительно базового адреса в программе (исходя из чего он назначается?).
С точки зрения программы - да, все так как вы описали. Но вот здесь у нас и начинается колдунство. Дело в том что "сегмент" делится на страницы, которые ОС может связать с произвольной областью физической памяти. Скажем, программа думает "вау, у меня четыре гига нулей!", а реально все эти четыре гига завернуты на одну единственную забитую нулями страничку. Таким образом, по факту никакого "базового адреса" сегмента давно уже нет, а данные в нем на самом деле раскиданы по физической памяти абсолютно произвольным образом. Просто ОС очень хорошо делает вид что у программы есть огромный шмат памяти, отданный ей в безраздельное пользование.
Цитата Сообщение от prado777 Посмотреть сообщение
1.1 Объем требуемого АП, рассчитанный на этапе компиляции, влияет на размер выделяемого АП или как вы написали "сегмент на 4 гига" и сколько там компилятор насчитал - это не важно, кусок все равно выделится одного размера??
По документам - да, программа всегда получает сегмент равный по размерам "сколько сможешь адресовать". Но смотри выше, кусок чисто виртуальный.
2. Стек, данные и код лежат в одном адресном пространстве. Модели памяти в которых код отдельно, данные отдельно были, но как-то не прижились.
2.1 Возвращаемое значение обычно пихается в регистр (E)AX. Если в регистр не влезает - как компилятор решит.
2.2 Да, если передавать функции ссылку, то фактически работаем с переменной на которую передана ссылки.
Цитата Сообщение от prado777 Посмотреть сообщение
Он добавляет смещение, которое соответствует ф-ции к этому 0x123 и переходит на получившийся адрес. Так?
Да. В то время был реальный режим, реальные адреса и всего этого колдунства со страницами не было.
Цитата Сообщение от prado777 Посмотреть сообщение
3. Выделяемый кусок памяти АП при выполнении exe - это ведь статическая память?
На уровне системы и процессора нет никакой статической и динамической памяти. Она есть только в голове программиста который условился что вот этот участок памяти навечно застолибили за глобальной переменной (статическая память), а вон тот будет переходить из рук в руки (динамическая память). Ну, еще бывает стек - почти тоже самое что динамическая память, только переход из рук в руки реализован на уровне процессора.
Цитата Сообщение от prado777 Посмотреть сообщение
А работаем мы из того же нашего выделенного адресного пространства программы. Так?
Да. "Сегмент" один на все.
1
5 / 5 / 1
Регистрация: 20.11.2017
Сообщений: 51
22.11.2017, 20:44  [ТС] 10
Хорошо с реальным режимом ясно, т.е. как видит это программа и ее разработчик, а теперь хотелось бы подробнее разобраться, что же за "колдунство" творит ОС.

1 . Вопрос Теперь у нас физ. память разбита на блоки - "страницы" у которых максимальное смещение допустим 1024 Кб . Для того, чтобы использовать эти "страницы", необходимо к ним обратиться. Обращаемся так:

1.1 У нас есть виртуальный адрес, который состоит из номера страницы и смещения в этой странице. Так вот в таблице вирт. страниц ищется страница с номером, взятым из виртуального адреса.

1.2 В найденной вирт. странице лежит физический адрес страницы памяти к которому добавляется смещение из вирт. адреса и в итоге мы попадаем по нужному физическому адресу. Такая идея?

2. Как назначается(ются) это виртуальный адрес? Исходя из смещений, которые были рассчитаны в процессе линковки? Он назначается при запуске? или уже во время линковки? Откуда они берутся?

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

4. И еще, хорошо, у нас выделилось там скажем 5 страничек где-то в RAM и все они , ну кроме последнего "набиваются данными и инструкциями программы", я верно понимаю? Но вот почему именно 5? От чего это зависит? Вы говорите, что все равно, т.к. память виртуальная,но ведь она связывается в последствии с физической? // про нули ваши не осознал//

5. А уже это все процессор через физ адреса обрабатывает.Верно?

Скорректируйте, пожалуйста, если где-то ошибся, я уже почти у цели.
0
2756 / 1910 / 569
Регистрация: 05.06.2014
Сообщений: 5,560
22.11.2017, 22:06 11
Цитата Сообщение от prado777 Посмотреть сообщение
1.2 В найденной вирт. странице лежит физический адрес страницы памяти к которому добавляется смещение из вирт. адреса и в итоге мы попадаем по нужному физическому адресу. Такая идея?
Да. Старшие биты виртуального адреса - индекс в таблице страниц, из которой берется базовый адрес страницы. Младшие биты виртуального адреса - смещение от этого базового адреса. С той поправкой что таблица страниц делается многоуровневой, чтоб в ней можно было оставлять пустые места. А то как-то накладно таскать громадную таблицу, из которой и нужно то записи три от силы.
Цитата Сообщение от prado777 Посмотреть сообщение
2. Как назначается(ются) это виртуальный адрес? Исходя из смещений, которые были рассчитаны в процессе линковки? Он назначается при запуске? или уже во время линковки? Откуда они берутся?
Очень просто назначается - в документации к ОС написано что вот эту половину адресов возьмет себе ОС, а вон ту половину программа. Куда конкретно в своей половине грузиться - на откуп левой пятки компилятора. При большом желании можно покопаться в настройках компилятора и найти там опции для ручного задания базового адреса секций. Но актуально это разве что для DLL, которые лезут в чужое адресное пространство и не знают заранее где там свободно.
Цитата Сообщение от prado777 Посмотреть сообщение
3. У нас под наш exe при запуске выделяется определенное кол-во таблиц страниц при помощи блока управления памятью, с которыми и работает exe передавая туда вирт. адреса и после их преобразования сначала в линейные, а потом в физические у нас получается, что этот exe как бы отображен в памяти, причем все эти странички, на которых он лежит, они в разных местах могут быть. Так?
Так. Плюс возможны страницы вообще не связанные ни с какой физической памятью. При попытке к ним обратиться будет вызвана специальная процедура, которая и разберется что с этим обращением делать. Например, подгрузит данные из свопа. Что позволяет загружать отображенные в память файлы "лениво" - "ну вот как произойдет попытка обращения к данным, так загрузим. А пока пусть на диске лежат".
Цитата Сообщение от prado777 Посмотреть сообщение
4. И еще, хорошо, у нас выделилось там скажем 5 страничек где-то в RAM и все они , ну кроме последнего "набиваются данными и инструкциями программы", я верно понимаю? Но вот почему именно 5? От чего это зависит?
У нас выделилось пять страничек в таблице страниц. Потому что в четыре страницы все не влезает. А вот выделилось ли RAM это большой вопрос. Скажем, если вы запускаете два экземпляра одной программы, ОС спокойно свяжет обе копии программы с одной областью RAM. Данные же все равно одинаковые, никто и не заметит. А если одна из копий попытается эти данные подправить, то сработает copy on write - ОС перехватывает попытку записи и разносит две копии программы по разным областям RAM. Ну, точнее разносит она не копии программы, а копии конкретно той страницы, которую попытались исправить.
Цитата Сообщение от prado777 Посмотреть сообщение
5. А уже это все процессор через физ адреса обрабатывает.Верно?
Процессор транслирует виртуальные адреса в физические. А в планку памяти да, передает физические адреса.
0
3505 / 2128 / 395
Регистрация: 09.09.2017
Сообщений: 8,847
22.11.2017, 22:22 12
Цитата Сообщение от Renji Посмотреть сообщение
2. Стек, данные и код лежат в одном адресном пространстве. Модели памяти в которых код отдельно, данные отдельно были, но как-то не прижились.
Кто вас так жестоко обманул? В контроллерах такое повсеместно
0
5 / 5 / 1
Регистрация: 20.11.2017
Сообщений: 51
23.11.2017, 18:49  [ТС] 13
Окей. 1 вопрос
1.1 Получается на этапе линковки у нас как происходит следующее: Выбирается какой- то адрес и относительно него рассчитываются смещения. Скажем адрес 1. Первая инструкция смещена на 1, 2-ая на 2, 3-яя на 3. Компилятор знает, что на все команды и данные ему нужно 6 байт. Далее при запуске exe, ОС даст нам какой-то вирт. адрес со смещением 3, которое было вычислено при линковке, затем, исходя из этого смещения выделяется нужное кол-во вирт. страниц в таблице, так?

1.2 Или у нас на этапе линковки проиходит так: выбирается начальный вирт. адрес, уже "согласованный с ОС из той пачки, которая под программы", ( допустим макс. смещение 4 байта ) . Затем линковщик относительно этого начального адреса начинает рассчитывать смещения каждой инструкции и как только получается объем страницы, он выделяет новый вирт. адрес, затем рассчитывает смещения уже относительно него и так до тех пор, пока вся программа не будет таким образом проадресована. Т.е адрес 15, смещения 1,2,3,4 ; адрес 16, смещения 1,2,3,4; адрес 17, смещения 1,2. И вот потом уже все это хоз-во при запуске exe начинает играть. Так?

2 вопрос
В физ. памяти эти страницы могут быть раскиданы, но в таблице страниц, вирт. страницы выделяются последовательно, начиная с вирт. адреса, А вот сколько этих вирт. страниц будет - зависит от смещений относительно этого адреса, которые были вычислены в процессе линковки . Верно?
0
2756 / 1910 / 569
Регистрация: 05.06.2014
Сообщений: 5,560
23.11.2017, 19:40 14
Цитата Сообщение от prado777 Посмотреть сообщение
1.2 Или у нас на этапе линковки проиходит так: выбирается начальный вирт. адрес, уже "согласованный с ОС из той пачки, которая под программы", ( допустим макс. смещение 4 байта ) . Затем линковщик относительно этого начального адреса начинает рассчитывать смещения каждой инструкции и как только получается объем страницы, он выделяет новый вирт. адрес, затем рассчитывает смещения уже относительно него и так до тех пор, пока вся программа не будет таким образом проадресована.
Линковщик генерирует непрерывный шмат кода и ставит пометку "загрузить этот шмат по адресу 0x12345000, с такими-то правами (например, только чтение/разрешено исполнение)". А как потом этот шмат будет распилен на страницы и линкеру, и программе абсолютно безразлично. Машинные инструкции все равно работают с адресами вида 0x12345678, а не 0x12345 (страница):0x678 (смещение). Трансляция виртуального адреса в физический осуществляется неявно и к ее механизмам обычное приложение никто не пустит. Ну, то есть пустит, но не напрямую, а через системные API вызовы, которые еще подумают разрешить или запретить и не пущать.
Цитата Сообщение от prado777 Посмотреть сообщение
В физ. памяти эти страницы могут быть раскиданы, но в таблице страниц, вирт. страницы выделяются последовательно, начиная с вирт. адреса, А вот сколько этих вирт. страниц будет - зависит от смещений относительно этого адреса, которые были вычислены в процессе линковки . Верно?
Ну да. Чем больше шмат кода, тем больше под него надо страниц. Сами страницы в таблице страниц идут по порядку, но данные могут быть раскиданы произвольно.
1
5 / 5 / 1
Регистрация: 20.11.2017
Сообщений: 51
23.11.2017, 20:32  [ТС] 15
Цитата Сообщение от Renji Посмотреть сообщение
"загрузить этот шмат по адресу 0x12345000
Это имеется в виду вирт. адрес, указывающий на начальную таблицу в таблице страниц? А потом уже, как было сказано выше, исходя из кол-ва смещений в программе, которые были рассчитаны в процессе линковки, у нас начинают последовательно выделяться страницы в таблице страниц, пока все инструкции не будут "упакованы". т.е. начинается все с одного вирт. адреса, который был сгенерирован линковщиком, но как бы для программы и для программиста он является физическим адресом начального сегмента в памяти, так?

И еще, шмат - этот термин обозначает, как я понимаю, набор адресов?
0
2756 / 1910 / 569
Регистрация: 05.06.2014
Сообщений: 5,560
23.11.2017, 21:14 16
Цитата Сообщение от prado777 Посмотреть сообщение
Это имеется в виду вирт. адрес, указывающий на начальную таблицу в таблице страниц? А потом уже, как было сказано выше, исходя из кол-ва смещений в программе, которые были рассчитаны в процессе линковки, у нас начинают последовательно выделяться страницы в таблице страниц, пока все инструкции не будут "упакованы". т.е. начинается все с одного вирт. адреса, который был сгенерирован линковщиком, но как бы для программы и для программиста он является физическим адресом начального сегмента в памяти, так?
Да, с точки зрения программы и программиста, 0x12345000 это физический адрес с которого начинается код программы. С точки зрения ОС - виртуальный адрес, с которого надо выделять страницы под загружаемый код.Страницы выделяются пока под весь код не хватит.
Цитата Сообщение от prado777 Посмотреть сообщение
И еще, шмат - этот термин обозначает, как я понимаю, набор адресов?
Под шматом я подразумеваю набор машинных инструкций, которые внутри exe собраны в один непрерывный блок. В память все же машинные инструкции загружаются, а не адреса и смещения.
1
5 / 5 / 1
Регистрация: 20.11.2017
Сообщений: 51
23.11.2017, 21:21  [ТС] 17
Спасибо Вам огромное !!!
0
5 / 5 / 1
Регистрация: 20.11.2017
Сообщений: 51
29.11.2017, 23:38  [ТС] 18
Добрый вечер, появился еще вопрос, начал разбираться со стеком, что называется на практике, написал простецкую прогу и
вывел адреса у каждой переменной.Все они изображены на картинке (сори за "кривоту").

На ней показано 5 шагов заплнения стека вызова:
1 шаг. Заполняется так называемый кадр стека (frame) ф-ции main(). Это ее локальные переменные.
Тут вроде все логично: смещение на 4 байта - Age, на 8 байт - Pi, на 12 байт - r. Вычитал,
что на x86 стек растет вниз. SP - вершина стека, FP - указатель на кадр.

2 шаг. Как дошли до вызова ф-ции, в стек добавляются пар-ры ф-ции frab() в обратном порядке (копии Age и Pi),
у которых смещения уже почему-то отличаются аж на (532 - 472) 60 байтов. Почему так? Ведь должно на 4, как я понимаю!
Или 472 - это уже другая "страница" виртуальной памяти?? Которая, как мы с Вами говорили,
находится уже в другом месте физической памяти, так? А та уже забилась.

Резервируется ячейка под возвращаемое значение, записывается в ret_adr значение регистра IP
и в registers записывается инфа, для возвращения состония ф-ции main() в состояние "до вызова",

3 шаг. Добавляем лок. переменные ф-ции frab() в стек и передаем ей управление ( fp и sp переместились).
Почему ret_val, ret_val, regist занимают всего, судя по смещениям, 4 байта???

4 шаг. Вычисляется сумма i = 30 + 3. Как только процессор доходит до return (RET), он кладет
в ret_val 33, восстанавливает сост. main().

5 шаг. Записывает в r значение 33.

Доп. вопросы
6.Операция взятия адреса & показывает физ. адрес или номер страницы в таблице страниц?
7. Тут мы передаем пар-ры (копии лок.переменных), которые имеют другой адрес.
А когда используем указатель, то используем адрес на лок. переменную в main(),
не создавая копию для передачи, но ведь указатель то все равно нужно сохр. в стеке, то есть
это те же 32 бита (для 32 х разр), так как же указатели защищают от переполнения стека? Место то
под них нужно все равно и так же, как и копии, 2 указателя запишуться на место копий. Объясните, пожалуйста.

Листинг:
int main() {
int Age = 30;
int Pi = 3;
int r = 0;

//call func
r = frab(Age,Pi);
retutn 0;
}

//difinition func
int frab(int x,int y) {
int i = x + y;
int o = 0;
return i;
}
Миниатюры
Адресация переменных и всей структуры программы на реальной памяти в ОС  
0
2756 / 1910 / 569
Регистрация: 05.06.2014
Сообщений: 5,560
29.11.2017, 23:52 19
Цитата Сообщение от prado777 Посмотреть сообщение
у которых смещения уже почему-то отличаются аж на (532 - 472) 60 байтов. Почему так? Ведь должно на 4, как я понимаю!
1) Дополнительное место скушала показывалка смещения.
2) Дополнительное место скушало сохранение старых значений регистров перед вызовом функции.
3) Что-то еще.
Короче, неявные расходы памяти никто не отменял.
0
5 / 5 / 1
Регистрация: 20.11.2017
Сообщений: 51
29.11.2017, 23:55  [ТС] 20
А как на счет вопросов в конце?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.11.2017, 23:55
Помогаю со студенческими работами здесь

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

Сегментная адресация памяти
Здравствуйте, читаю небольшой материал про процессор 8086 и появившийся в нем режим сегментации...

Туториал по написанию реальной программы
Всем привет. Я изучаю язык программирования C# и понимаю, что чтобы научиться реально...

Адресация памяти, помогите разобраться
Имеется контроллер STM32F100RB. Исходя из рисунка видно, что у нас имеется 4Гб, к которым мы можем...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru