Какие типы памяти доступны программисту при разработке программ

Обновлено: 15.05.2024

В настоящее время этот вопрос не подходит для нашего формата вопросов и ответов. Мы ожидаем, что ответы будут подкреплены фактами, ссылками или опытом, но этот вопрос, скорее всего, вызовет дебаты, аргументы, опросы или расширенное обсуждение. Если вы считаете, что этот вопрос можно улучшить и, возможно, снова открыть, посетите справочный центр для получения инструкций.

Кажется, чтобы уметь программировать, нужно помнить все виды синтаксиса. Если у человека нет хорошей памяти для запоминания имен, будет ли ему сложнее научиться программировать?

Сейчас я не трачу весь день на программирование, но каждый день трачу некоторое время на программирование. И я программирую на куче языков, которые не похожи друг на друга. Я программирую на C, Java, Javascript, Lisp, VBA, PL/SQL, Ruby, Python, Perl, Smalltalk и даже время от времени немного на Прологе. Я просто смотрю синтаксис.

Конечно, университеты учат этому так, как будто вам нужна хорошая память, что совершенно глупо. Мой особенно известен тем, что требует, чтобы итоговые экзамены по компьютерным наукам стоили не менее 50% (всегда закрытые книги), а промежуточные экзамены обычно составляют не менее 30-40%.

19 ответов 19

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

+1. Это действительно становится второй натурой. Я оглядываюсь на код и даже не помню, чтобы выполнял какие-либо правила форматирования, которым следую.

Кажется, нужно помнить все виды синтаксиса, чтобы программировать говорить на естественном языке.

Если у человека плохая память на запоминая слова названия, будет ли сложнее научиться программировать говорить?

Не может быть, чтобы люди обладали "естественными" способностями к языкам, не так ли?

Не может быть, чтобы у нас было низкоуровневое нейронное оборудование только для изучения языков, не так ли?

В программировании используются искусственные языки, которые следуют многим правилам естественных языков.

Естественные языки обладают немного большей гибкостью, чем языки программирования.

Грамматика по-прежнему строгая. правила есть очень есть которые Но

Если вы можете говорить, вы можете научиться программировать, не запоминая ничего сверх того, что вы запомнили, когда учились говорить.

Если вы говорите о кратковременной памяти, то да. программист должен уметь одновременно обрабатывать несколько битов информации при программировании/решении задач.

Если вы говорите о долговременной памяти, то не совсем так. Существует множество руководств и справочников + инструменты, которые могут существенно помочь в воспроизведении информации. Конечно, запоминание этой долгосрочной информации сделает вас более быстрым разработчиком (в целом), но это не обязательное условие.

+1 За полезное сравнение полезности кратковременной и долговременной памяти в связи с вопросом. Ждал, когда кто-нибудь это сделает.

Хорошая память абсолютно необходима, но не по очевидным причинам.

Запоминание подробностей о конкретных алгоритмах, библиотеках, именах переменных и т. д. очень удобно, но не очень важно. У вас есть Google, DuckDuckGo, справочные страницы, документация по конкретному языку и интеллектуальные редакторы, которые помогут со всем вышеперечисленным. Это помогает, если вам не нужно полагаться на эти костыли, но вы прекрасно справитесь, если они вам время от времени понадобятся.

Память важна для сохранения деталей того, над чем вы работаете, в активной кратковременной памяти. Возможность визуализировать дизайн, поток данных, алгоритмы, структуры данных и то, как все они взаимодействуют, чтобы делать то, что делает ваш продукт, отличает нормального программиста от великого программиста. Когда вы активно этим занимаетесь, создается впечатление, что вы успешно жонглируете огромным количеством мячей, катаясь на одноколесном велосипеде.

Это часто называют зоной. Прерывания, глупые вопросы, боссы, которым нужны отчеты TPS, — все это выталкивает вас из этой зоны.

Чем лучше у вас память, тем легче попасть в зону, тем проще в ней остаться и тем легче вернуться в нее после перерыва.

Если у вас есть проблемы с такой памятью, я бы посоветовал изучить техники медитации и трюки с памятью, поскольку чем легче становится ваша память, тем большего успеха вы добьетесь как программист.

На самом деле я бы сказал, что требования к памяти сокращаются, если вы лучше разбиваете программу на модули и правильно называете вещи.Если у вас есть двухстраничный метод с 20 переменными, вам нужно помнить гораздо больше, чем если бы у вас был 5-строчный метод с вызовами других хорошо названных методов для выполнения подзадач. Кроме того, каждый раз, когда вы хотите изменить что-то настолько сложное, вы должны войти в «зону», чтобы сделать это. А если проще, то можно просто внести изменения. Я бы сказал, что «зона» — это пассив.

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

Почему в этом мире был только один голос? Вы не сможете правильно спроектировать свой код, не помня, как он вписывается в окружающий его материал. Большая часть современного программирования направлена ​​на сокращение количества деталей, которые это влечет за собой, но это просто уменьшает объем, который вы должны помнить, а не тот факт, что вы должны помнить это, чтобы выполнять свою работу.

Я собираюсь пойти против течения и сказать «да». Хорошая память — отличный актив для программиста. Свою память я всегда рассматривал как недостаток программирования, поэтому я придумал несколько приемов, чтобы компенсировать свой недостаток:

Вы должны помнить, как пишется эта переменная (которую вы использовали тремя строками ранее). Если вы не можете научиться использовать Intellisense (или любую другую форму автозаполнения в вашем редакторе или IDE).

Вы должны быть в состоянии быстро вспомнить, что вы делали в прошлый раз, когда работали над этим проектом. Это могло быть несколько дней назад, а могло быть и перед обедом. Если не умеете, научитесь записывать. Держите рядом с собой блокнот и записывайте, что вы делали (или делаете), пункты TODO и все, что вам нужно помнить о том, как текущий код, над которым вы работаете, сочетается друг с другом.

Отладка и контроль качества — это сложно. В идеале вы должны вести очень подробный блокнот о шагах, которые вы предприняли, пытаясь воспроизвести ошибку или что-то отладить. Я знаю, что должен это сделать, но все еще борюсь с этим.

Надеюсь, это поможет!

Руководство по проведению собеседований для партизан (версия 3.0) — это общепринятый справочник, в котором отмечается, что ум и выполнение задач являются важными моментами программирования. Умный действительно включает в себя некоторые навыки памяти, но не обязательно так много, как вы думаете.

Intellisense может сильно помочь, когда дело доходит до синтаксиса, если вам нужна помощь в этом вопросе. Знание того, как вы учитесь, чтобы вы могли быстро применить то, что вы узнали, более важно, чем способность отвечать на простые вопросы.

Я полагаю, что запоминание имен — это когнитивная функция, несколько отличающаяся от процесса запоминания, который отличается от запоминания словарного запаса. Были случаи, когда люди, получившие черепно-мозговую травму, полностью потеряли способность запоминать имена, в то время как в остальном они могли нормально функционировать.

Поэтому я бы сказал, что способность запоминать имена не связана с изучением языков программирования.

Однако было бы полезно запомнить логические закономерности, правила и словарный запас.

Я почти уверен, что вы правы. Индикатор типа Майерс-Бриггс говорит, что INTP (которые особенно подходят для того, чтобы стать программистами) с трудом запоминают имена людей. Я знаю, что это верно в моем случае. Я могу вспомнить имена ваших питомцев, номерной знак вашей машины и то, куда я положил распечатку трассировки стека, которую вы дали мне в прошлом году, со странными новыми строками как 0x0D0A0D. Хотя твое собственное имя я забуду через 10 минут. (Когда я был моложе, мне потребовалось три года, чтобы узнать имена всех игроков моей футбольной команды.)

Нет. Глубина памяти инструментов (Intellisense, Google, компиляторы, генераторы кода) бесконечна по сравнению с человеческой памятью. Так что программист с хорошей памятью ничем не лучше программиста с дыркой в ​​голове.

Что на самом деле нужно программистам, так это "пиковая скорость получения фокуса", когда они переключаются между уровнями абстракции. Чем быстрее вы можете, тем лучше вы как программист. У некоторых частота сердечных сокращений составляет около 500 мс, и с приходом первой волны крови в мозг вы концентрируетесь. У некоторых упорные часы округлены до цикла курения, около 2 часов. Некоторым нужен утренний душ, так что около 24 часов. и т.д. Разница между хорошим и плохим программистом когда-то была объявлена ​​кратно 1:80 лет назад, и эта разница только увеличивается.

Нет, вам просто нужно понять, как работает Google, чтобы получить то, что вы хотите

У меня ужасная память, но я отлично умею гуглить ^_^

Со всей серьезностью, если вы знаете, где найти синтаксис, вам не нужно его запоминать. Вот для чего нужны IntelliSense, файлы справки, справочные руководства, Интернет и т. д.

Во-первых, научиться программировать сложно для всех. Хорошая память помогает, я уверен. Но самоотверженность и любовь к обучению на протяжении всей жизни более ценны. Изучение синтаксиса, как и все остальное, это повторение.

В навыках программирования нет ничего волшебного или сверхчеловеческого. Просто потратьте на это около 10 000 часов. и вы станете мастером, как и любой другой навык. Конечно, это 10 000 часов тренировок, а не слепое и тупое повторение прошлых ошибок.

Вы написали этот пост на английском языке с правильным синтаксисом. Очевидно, вы можете вспомнить, как использовать язык. Вам просто нужно выучить новый язык и использовать его достаточно часто, чтобы всегда понимать его правильно. В отличие от языков, ориентированных на человека, языки компьютерного программирования всегда дадут вам знать, когда вы использовали неправильный синтаксис, так что это на самом деле проще. :-)

Считается, что хорошим программистом является практика, практика с алгоритмами больше, чем с языками, и благодаря этому вы в конечном итоге запомните то, что используете чаще всего, в остальном всегда есть google =P

Отличная память может быть обоюдоострой.

Если вы сможете одновременно обрабатывать в голове десятки битов информации, вам будет намного легче разобраться (и, надеюсь, переписать) этот ужасный кусок устаревшего кода, который имеет решающее значение для проекта, но настолько сложен, что все еще боится прикоснуться к нему.

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

Изучение синтаксиса языка программирования не требует большой памяти. Как уже говорили другие, синтаксис настолько закрепляется в вашей памяти, что быстро становится второй натурой. Вы когда-нибудь забывали, по какой стороне дороги вы должны ехать? Какие арифметические символы обозначают сложение и вычитание? Если нет, вы без особых проблем освоите наиболее распространенные части синтаксиса выбранного вами языка и сможете искать менее распространенные части, когда они встречаются.

Некоторые библиотеки содержат сотни или тысячи функций, классов и/или методов. Постороннему человеку научиться пользоваться всем этим функционалом может показаться невыполнимой задачей. Но почти всегда в библиотеке есть какая-то базовая структура. Вместо того, чтобы пытаться запомнить все эти функции, умный программист пытается понять, как устроена библиотека и что она может делать. После этого обычно довольно легко найти нужную функцию, когда она вам нужна.

В этой серии, состоящей из нескольких частей, я стремлюсь демистифицировать концепции, лежащие в основе управления памятью, и более подробно рассмотреть управление памятью в некоторых современных языках программирования. Я надеюсь, что эта серия даст вам некоторое представление о том, что происходит под капотом этих языков с точки зрения управления памятью. Изучение управления памятью также поможет нам писать более производительный код, поскольку то, как мы пишем код, также влияет на управление памятью независимо от метода автоматического управления памятью, используемого языком.

Управление памятью – это процесс контроля и координации доступа программного приложения к памяти компьютера. Это серьезная тема в программной инженерии, которая смущает некоторых людей, а для некоторых является черным ящиком.

Что это?

Когда программное обеспечение работает в целевой операционной системе на компьютере, ему требуется доступ к ОЗУ (оперативной памяти) компьютера, чтобы:

  • загрузить собственный байт-код, который необходимо выполнить
  • хранить значения данных и структуры данных, используемые исполняемой программой
  • загрузить все системы времени выполнения, необходимые для выполнения программы

Когда программа использует память, она использует две области памяти, помимо пространства, используемого для загрузки байт-кода, памяти стека и кучи.

Стек

Стек используется для статического выделения памяти, и, как следует из названия, это стек по принципу «последним вошел – первым вышел» (LIFO) (подумайте об этом как о стеке ящиков).

  • В связи с этим процесс хранения и извлечения данных из стека выполняется очень быстро, так как поиск не требуется, вы просто сохраняете и извлекаете данные из самого верхнего блока в нем.
  • Но это означает, что любые данные, хранящиеся в стеке, должны быть конечными и статическими (размер данных известен во время компиляции).
  • Здесь данные выполнения функций хранятся в виде кадров стека (так что это фактический стек выполнения). Каждый кадр представляет собой блок пространства, в котором хранятся данные, необходимые для этой функции. Например, каждый раз, когда функция объявляет новую переменную, она «заталкивается» в самый верхний блок стека. Затем каждый раз, когда функция завершается, самый верхний блок очищается, поэтому все переменные, помещаемые в стек этой функцией, очищаются. Их можно определить во время компиляции из-за статического характера данных, хранящихся здесь.
  • Многопоточные приложения могут иметь стек для каждого потока.
  • Управление памятью стека является простым и понятным и осуществляется операционной системой.
  • Обычно в стеке хранятся локальные переменные (типы значений или примитивы, примитивные константы), указатели и фреймы функций.
  • Здесь вы можете столкнуться с ошибками переполнения стека, поскольку размер стека ограничен по сравнению с кучей.
  • Существует ограничение на размер значения, которое может храниться в стеке для большинства языков.


Стек используется в JavaScript, объекты хранятся в куче и используются при необходимости. Вот такое же видео.

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

  • Он медленнее, чем стек, так как процесс поиска данных более сложен, но может хранить больше данных, чем стек.
  • Это означает, что здесь можно хранить данные с динамическим размером.
  • Куча совместно используется потоками приложения.
  • Из-за своей динамической природы куча сложнее в управлении, и именно здесь возникает большинство проблем с управлением памятью, и именно здесь вступают в действие решения по автоматическому управлению памятью из языка.
  • Обычно в куче хранятся глобальные переменные, ссылочные типы, такие как объекты, строки, карты и другие сложные структуры данных.
  • Здесь вы можете столкнуться с ошибками нехватки памяти, если ваше приложение попытается использовать больше памяти, чем выделенная куча (хотя здесь есть много других факторов, таких как GC, сжатие).
  • Как правило, размер значения, которое может храниться в куче, не ограничен. Конечно, существует верхний предел объема памяти, выделяемой приложению.

Почему это важно?

В отличие от жестких дисков объем оперативной памяти не безграничен. Если программа продолжает потреблять память, не освобождая ее, в конечном итоге она исчерпает память и выйдет из строя или, что еще хуже, приведет к сбою операционной системы. Следовательно, программы не могут просто продолжать использовать оперативную память по своему усмотрению, поскольку это приведет к тому, что другим программам и процессам не хватит памяти. Таким образом, вместо того, чтобы позволить разработчику программного обеспечения разобраться с этим, большинство языков программирования предоставляют способы автоматического управления памятью. И когда мы говорим об управлении памятью, мы в основном говорим об управлении памятью кучи.

Разные подходы?

Поскольку современные языки программирования не хотят обременять (больше похоже на доверие 👅) конечного разработчика управлением памятью своего приложения, большинство из них разработали способ автоматического управления памятью. Некоторые старые языки по-прежнему требуют ручного управления памятью, но многие предоставляют изящные способы сделать это. Некоторые языки используют несколько подходов к управлению памятью, а некоторые даже позволяют разработчику выбрать то, что лучше для него/нее (хорошим примером является C++). Подходы можно разделить на следующие категории

Ручное управление памятью

По умолчанию язык не управляет памятью за вас, вы сами можете выделять и освобождать память для создаваемых вами объектов. Например, С и С++. Они предоставляют методы malloc , realloc , calloc и free для управления памятью, и разработчик должен выделять и освобождать память кучи в программе и эффективно использовать указатели для управления памятью. Скажем так, это не для всех 😉.

Сборка мусора (GC)

Приобретение ресурсов — это инициализация (RAII)

В этом типе управления памятью выделение памяти для объекта привязано к его жизненному циклу, то есть от создания до уничтожения. Он появился в C++, а также используется в Ada и Rust.

Автоматический подсчет ссылок (ARC)

Это похоже на сборщик мусора с подсчетом ссылок, но вместо запуска процесса среды выполнения с определенным интервалом инструкции сохранения и освобождения вставляются в скомпилированный код во время компиляции, и когда ссылка на объект становится равной нулю, она автоматически очищается как часть выполнения без любая программная пауза. Он также не может обрабатывать циклические ссылки и полагается на то, что разработчик справится с этим, используя определенные ключевые слова. Это функция компилятора Clang, которая обеспечивает ARC для Objective C и Swift.

Владение

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

Владение в Rust

Мы только что коснулись управления памятью. Каждый язык программирования использует свою собственную версию и использует разные алгоритмы, настроенные для разных целей.В следующих частях серии мы более подробно рассмотрим точное решение для управления памятью на некоторых популярных языках.

Современные методы разработки программного обеспечения призваны обеспечить максимально быструю скорость внесения изменений в приложение. Действительно, методы Agile-разработки, на которые в настоящее время ориентируется большинство усилий разработчиков, ориентированы на эффективность пропускной способности. Часто идут на жертвы, чтобы доставить код вовремя; часто в первую очередь приносится в жертву глубокое тестирование кода приложения. Проблемы с памятью и производительностью являются одними из самых сложных для решения и часто остаются незамеченными, особенно если основная причина связана с размером или адресацией переменной и поэтому является прерывистой или условной.

Действительно большие наборы данных усугубляют проблему эффективного тестирования изменений приложений. Оперативная память, которая используется неэффективно, может стать неадресуемой или фрагментированной. Многопоточное или многопроцессорное приложение может создавать уникальные проблемы с памятью для разработчиков, когда используется адресация переменных по ссылке.

Разработчики C, C++ и Fortran, а также те разработчики, которые используют Python для использования неуправляемых библиотек, имеют мощный инструмент, который они могут легко использовать для поиска и устранения даже самых неуловимых проблем кодирования, связанных с памятью.

Что такое утечка памяти?

Утечка памяти в неуправляемом приложении относится к памяти или указателям на адреса памяти, которые после освобождения становятся недоступными или непригодными для использования (осиротевшими), но чаще используется для описания многих типов проблем, связанных с памятью.

С практической точки зрения, если память компьютера «грязная», заблокирована, заполнена неизвестными или неожиданными значениями, недоступна или неизменна, разработчики будут подходить к задаче сортировки примерно таким же образом; сортировка проблем, связанных с памятью, общеизвестно проблематична и требует мощных инструментов с глубоким знанием того, как работает управление памятью.

Что вызывает утечку памяти?

Короткий ответ на вопрос о том, что вызывает утечку памяти, таков: «мы делаем». разработчики пишут код, который становится приложением с уязвимостями. В списке распространенных уязвимостей и уязвимостей (CVE) подробно описаны такие уязвимости, как утечка памяти.

Вот почему правильные инструменты — лучшее оружие разработчика в борьбе за совершенство кода.

Существует множество причин, по которым приложение может потерять память. Я могу создать блок адресуемой памяти, но позже потерять его:


В приведенных выше строках я потерял возможность использовать первое выделение, и эта память теперь потеряна для приложения, и может потребоваться перезапуск хоста для восстановления потерянной памяти.

Я также могу перезаписать выделенное мне пространство памяти на неуправляемых языках. Я могу написать строковое значение, длина которого больше выделенного места; хотя технически это переполнение памяти, такого рода проблемы очень трудно сортировать, и для их решения используются те же дисциплины, что и для утечки памяти.

Есть также потенциальные проблемы с указателями, несоответствиями в выделении/освобождении памяти, проблемами с неинициализированной памятью и проблемами в нескольких стеках программных инструкций или программных потоках, которые следует учитывать.

Управление памятью неуправляемых приложений считается одной из самых сложных задач отладки при разработке. Для эффективной сортировки программного обеспечения требуются знания и инструменты.

Технология отладки памяти

Решение TotalView для отладки памяти обеспечивает обнаружение утечек C и C++, обнаружение переполнения памяти и множество других проверок памяти. Разработчики обычно используют пользовательский интерфейс TotalView для поиска проблем с памятью в своей программе, но могут не знать об интерфейсе на основе сценариев для использования в автоматизированных средах, таких как развертывание CI.

Наша базовая технология отслеживания памяти не требует перекомпиляции или специальной сборки целевого приложения. Вместо этого он динамически проксирует между вашей программой и базовыми системными вызовами функций памяти, чтобы отслеживать все действия, связанные с памятью. Это решение позволяет разработчикам проверять использование памяти целевыми приложениями "на лету" с минимальными затратами времени выполнения.

Интерфейс сценариев TotalView, memscript, позволяет приложениям тестировать утечки памяти в среде автоматизированного тестирования. Сценарий создает журналы вывода и файлы записи памяти, включая результаты обнаружения утечек и уведомления о любом незаконном использовании памяти. Если обнаружены утечки памяти или ошибки использования памяти, разработчики могут загрузить сгенерированные файлы записи памяти в пользовательский интерфейс TotalView и проанализировать использование памяти программой. Функция отладки памяти на основе скриптов обеспечивает основу для интеграции в вашу систему непрерывной интеграции.

Отличный курс. Обновил все мои представления о программировании встроенных систем спустя долгое время. Очень хороший вводный курс для первокурсников кампуса, которым нужно начать работать над разработкой системного ПО.

Этот курс дал очень хороший практический опыт работы со встроенным системным программным обеспечением. Я изучил эти темы теоретически, а также лучше понял концепцию с заданиями.

Типы памяти, сегменты и управление

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

Проподаватели

Placeholder

Алекс Фосдик

Текст видео

В этом видео мы обсудим память кода и сегмент кода. Скомпилированная программа в первую очередь размещает информацию в двух типах памяти, коде и данных. Как и сегмент данных, сегмент кода можно разбить на множество различных подсегментов и характеристик. Третий тип памяти, регистровая память, используется программой для запуска ассемблерных инструкций и взаимодействия с микроконтроллером. Выполнение программы — это серия инструкций, которые извлекаются из нашей памяти кода. Регистры процессора используются почти в каждой выполняемой ассемблерной инструкции. Для этого взаимодействия ассемблерные инструкции должны знать точные сведения о том, какие регистры и какие ячейки памяти запрограммированы для использования каждой инструкцией. Эта информация закодирована непосредственно в инструкциях. Сегмент кода представляет собой часть скомпилированной памяти, которая содержит всю нашу исполняемую программу. Этот сегмент в основном содержит весь наш скомпилированный код, а также немного памяти программных данных. Сегмент кода помещается в память, такую ​​как флэш-память, которая доступна только для чтения во время выполнения. Это делается для защиты вашего кода от перезаписи, а также из соображений безопасности. Память кода может быть доступна для записи во время выполнения, но требует дополнительного взаимодействия и разрешений для записи данных в зависимости от реализации? Память кода имеет другие ограничения, такие как задержка, долговечность, но у нее есть большое преимущество, поскольку она является энергонезависимой памятью. Из-за этого память, такая как флэш-память, используется для хранения нашего программного кода, не опасаясь потери данных при отключении питания. Давайте погрузимся в подсегменты сегмента кода. К ним относятся такие вещи, как таблица векторов прерываний, ваша написанная программа, постоянные данные только для чтения, код инициализации, загрузчики и конфигурация флэш-памяти. Подобно сегменту данных, файл компоновщика указывает, на какую физическую память сопоставляются сегменты кода. Подсегменты непрерывно отображаются в эту область, начиная с адреса 0. Здесь у нас есть пример того, как этот сегмент кода и подсегменты отображаются в физической памяти. Размеры каждого из этих сегментов зависят от реализации, будь то архитектура, компилятор или ваша программа. Начиная с адреса 0, у нас есть таблица векторов. Таблица векторов представляет собой таблицу адресов функций, которая соответствует определенным подпрограммам прерывания. Мы обсудим прерывание более подробно на последующем курсе. Но подпрограммы прерывания подобны специализированным подпрограммам, которые имеют приоритет над вашей основной программой. Они вызываются синхронно и должны быть определены особым образом. Когда вы разрешаете прерывание и пишете подпрограмму функции для этого обработчика прерывания, вы должны отобразить адрес функции прерывания из памяти кода в нужное место в таблице. Таким образом, когда ЦП нужно ответить на запрос прерывания, вызвав соответствующую функцию прерывания, он может просмотреть эту таблицу и найти память для кодирования, где находится эта функция. В общем, место для размещения в таблице векторов по адресу 0 довольно стандартно. Но это можно настроить в наших архитектурах карт. Размер подсегмента будет установлен на основе архитектуры, поскольку разные архитектуры поддерживают разное количество прерываний. Следующий раздел, который мы обсудим, — это текстовый сегмент. Текст представляет собой сегмент, в который компилируется весь написанный вами фактический код. Это включает в себя вашу основную функцию и все ваши программные подпрограммы, которые вы пишете. Размер вашего текстового раздела будет зависеть от того, насколько велика ваша программа. Кроме того, есть много функций, которые можно добавить к тексту из стандартной библиотеки C. Это включает в себя такие вещи, как вызов вашей основной функции, а также то, что вы поворачиваете из своей основной функции. Раздел данных только для чтения или данных RO иногда принадлежит как .const, и мы обсуждали это ранее. Здесь определены наши постоянные переменные. Вы не должны иметь возможность изменять свои постоянные данные.Попытка перезаписать данные, помещенные во флэш-память, может вызвать исключение процессора или операция может просто ничего не делать в зависимости от архитектуры. Это связано с тем, что память кода требует дополнительных взаимодействий с контроллером флэш-памяти для записи в нее данных. Подсегменты .pinit и .cinit используются при инициализации. Все ваши значения данных инициализации хранятся в энергонезависимой памяти данных до запуска программы. Это должно иметь смысл, потому что ваша память данных в SRAM потеряет свои данные после отключения питания. Начальные значения должны работать каждый раз при запуске вашей программы. Это связано с тем, что данные инициализации хранятся в вашей памяти кода, а затем загружаются в память данных при запуске. В общем, компилятор может оптимизировать хранение констант с одной переменной, если он знает, что их можно использовать только один раз. Однако для больших фрагментов данных инициализации, таких как массивы или строки, они сохраняются в таких областях, как данные только для чтения. Кроме того, существуют связанные подпрограммы, которые помогают выполнять фактический процесс инициализации данных. Это двойной удар по накладным расходам, поскольку для инициализации данных требуется как память кода, выделенная для начальных значений, так и процесс инициализации. В зависимости от архитектуры и компилятора эти разделы могут иметь разные имена или разные реализации. Однако вы, вероятно, увидите подсегменты с похожими именами .pinit, .cinit, .ctors, .init_array и .init. Некоторые встроенные приложения могут также использовать такие языки, как C++, в дополнение к C. В этом случае некоторые разделы могут быть специфичными для создания и уничтожения объектов C++. Последний подсегмент, который вы можете увидеть, связан с Bboot или загрузчиками и конфигурацией флэш-памяти. Как и прежде, встроенные системы нуждаются в методе установки кода. Использование внешних программных загрузчиков, которые подключаются непосредственно к процессору, дорого обходится и требует дополнительного оборудования. Наборы разработчика, которые мы используем в этом классе, используют встроенный процессор для программирования наших контроллеров маркеров через более дешевый и более стандартный интерфейс, такой как USB. Таким образом, мы можем избежать использования этих внешних программистов. Эти дополнительные встроенные процессоры называются внешним загрузчиком или прошивальщиком. В качестве альтернативы вы можете зарезервировать небольшой сегмент памяти кода для работы в качестве установщика. Загрузчик будет небольшой программой, которая при перезагрузке ищет сигнал на одном из своих коммуникационных интерфейсов, сигнализирующий об установке программы. Если он это видит, он перезаписывает текущую флэш-память новой программой. Если он ничего не видит, он просто вызовет текущую загруженную программу и начнет выполнение программы. Это уменьшит объем места, которое у вас есть для вашей программы, но также уменьшит количество оборудования, необходимого для установки. Этот процесс на самом деле очень сложный, и позже у него будет свое видео. Последнее замечание об этих сегментах кода и стандартных функциях C. Вам не нужно автоматически включать это. Компиляторы будут автоматически использовать некоторые стандартные функции C при компиляции вашего кода. Вы можете избежать добавления всех этих дополнительных подсегментов, написав свою собственную бета-версию металла C без потока компилятора стандартной библиотеки. Или написав свою собственную сборку напрямую. Однако это не рекомендуется, поскольку некоторые функции библиотеки стандартов значительно облегчают написание ваших программ. Например, определение того, что происходит при запуске и завершении программы. Кроме того, он сопоставит неподдерживаемые для вашей архитектуры операции с эквивалентными программными процессами. Память кода содержит нашу программу, а также в некоторых случаях наши данные. Память кода обычно намного больше нашей памяти данных, потому что память кода не предназначена для перезаписи во время выполнения. Когда мы устанавливаем программный код, мы хотим, чтобы эта информация сохранялась между циклами питания. Более продвинутые архитектуры со встроенной поддержкой ОС позволяют записывать и устанавливать память кода во время работы процессора. Но большинство микроконтроллеров не поддерживают это таким образом. Для установки новой программы требуется особый процесс взаимодействия с флэш-памятью. Однако то, как мы разбили память кода программы на сегменты кода, очень похоже на то, как мы разделили нашу память данных на более мелкие подсегменты данных.

Читайте также: