Вы исходите из плохой предпосылки:
Я понимаю, как адресное пространство разделено на: код, данные, стек и кучу.Однако у меня возникают проблемы с отображением того, куда и куда направляется данный код C.
Адресное пространство не разбивается таким образом.Адресное пространство содержит память.Память, используемая для стека, неотличима от памяти, используемой для кучи.Единственное, что делает стек стеком, - это то, что он выделяется в приложении с помощью указателя стека.Единственная вещь, которая делает кучу кучей, это то, что в приложении есть менеджер кучи.Вы могли бы выделить память из кучи и назначить ее указателю аппаратного стека, а ваша память - это и куча, и стек.
Вот еще одно неправильное представление:
Я знаю, что: глобальныйпеременные находятся в разделе данных.статические переменные находятся в разделе данных.локальные переменные находятся в секции стека.Динамическое выделенное пространство находится в разделе кучи.
Чем отличаются работники между ассемблерами, компоновщиками и системами.Однако рациональные ассемблеры позволяют пользователю определять свои собственные именованные разделы.Во многих ассемблерах я мог создавать Bobs_Data_Section, Freds_Data_Section и Sams_Data_section и помещать глобальные переменные в каждый из них.
В большинстве (но не во всех) компиляторах программист не может контролировать, как он собирается создавать разделы,Нет никакой гарантии, что компилятор поместит глобальные переменные в раздел под названием «данные».Фактически, глобальные переменные и статические локальные переменные могут находиться в одном и том же разделе.
Такие «разделы» обычно являются только входными данными для компоновщика.Компоновщик группирует разделы, определенные ассемблером и компилятором, в области памяти с общими атрибутами доступа.То, что входит в компоновщик, как, скажем, секция «данных», выходит из компоновщика в виде инструкций в исполняемом файле для создания страниц для чтения / записи.
У меня есть вопросы при включении библиотекив программу, где она находится в адресном пространстве?
Итак, теперь вы столкнулись с проблемой того, как вы пытаетесь узнать, как все работает.Если вы рассматриваете адресное пространство процесса как просто память, вы можете загрузить библиотеку куда угодно.Загрузчик программы читает инструкции в исполняемом файле и создает страницы с правильными атрибутами (например, readonly / noexecute, read / write, readonly / execute) в любом месте доступного адресного пространства.
Если вы просматриваете адреспространство как разделение на код, данные и т. д. загрузка библиотек становится проблематичной.Это заставляет меня задуматься, почему школы и книги продолжают преподавать, используя эти бессмысленные понятия.