Я знаю цель каждого сегмента, но мне было интересно кто на самом деле реализует их в таких языках, как с или с ++?
Написаны ли они программистами компилятора c / c ++, когда пишут реализацию языка? Или эти сегменты реализованы на уровне ОС / аппаратного обеспечения (возможно, когда ОС выбирает адресное пространство для программы)?
Я представляю стек в виде простой структуры c, которая помещается в стек для каждого вызова функции. Я представляю кучу как динамический массив и так далее …
Это немного схематично — архитектуры HW, модели памяти и т. Д. Все влияют на то, как реализация C / C ++ может содержать «сегменты». У более старых процессоров были ограничения, что приводило к более сложному набору «сегментов» (iAPX 286 — помните?). Так что просто примите это как грубое вступление, Google для модных слов, …
Код объекта содержит код, полученный из исполняемых операторов: байты, полученные из собранных машинных инструкций. Это перейдет в сегмент кода, который (как правило) приведет к сегменту памяти, защищенному от записи.
Код объекта содержит данные: байты, являющиеся результатом собранных операторов определения данных, с некоторой инициализацией (или по умолчанию, ноль в случае C / C ++). Это войдет в сегмент данных без ограничений доступа.
Стек требуется в зависимости от того, как работает ваш ЦП: отправка адреса возврата в стек, с наиболее эффективной конвенцией передачи параметров, также путем передачи параметров функции. «Фрейм стека» частично «условно», но обычно он состоит из адреса возврата и параметров; дополнительное пространство зарезервировано для локальных переменных: один набор для каждого экземпляра (что важно, если функция рекурсивная).
Куча — это просто область памяти, из которой обслуживаются выделения (malloc, new). Обычно он выделяется за пределы сегмента кода и данных. Стеки могут быть извлечены из кучи — здесь все зависит от того, есть ли у вас один сегмент стека или несколько (подумайте о потоках).
Кроме того, обратите внимание, что существует несколько «форматов» или «языков» объектного кода, то есть способов определения этих сегментов в объектном коде. Это зависит от того, что может обработать системный загрузчик: один такой формат известен как «a.out», другой — «ELF». Компиляторы должны придерживаться формата и возможностей.
Написаны ли они программистами компилятора c / c ++, когда пишут реализацию языка? Или эти сегменты реализованы на уровне ОС / аппаратного обеспечения (возможно, когда ОС выбирает адресное пространство для программы)?
Точки входа сегмента в основном управляются на этапе связывания (и программе связывания) цепочки инструментов.
В этом смысле, да, они реализованы разработчиками компилятора.
Вы можете предоставить свой собственный скрипт компоновщика, в котором вы можете указать, по каким конкретным адресам памяти должны появляться эти сегменты, и относятся ли эти адреса памяти к ПЗУ или ОЗУ.
Я представляю стек в виде простой структуры c, которая помещается в стек для каждого вызова функции. Я представляю кучу как динамический массив и так далее …
Это вообще не так просто Боюсь: