L-10.YkazatelivyazikeSi
В архитектуре ЭВМ фон Неймана (базовый вычислитель), одним из основных свойств является линейность и однородность оперативной памяти, а отдельные ячейки памяти идентифицируются адресами. То, что в языках высокого уровня называют переменной , на уровне машинного кода представляет собой не более чем область памяти, то есть несколько ячеек памяти, расположенных подряд, или, иначе говоря, имеющих последовательные адреса. Под адресом области памяти понимается наименьший из адресов ячеек, составляющих область. Для нас здесь важно то, что любая переменная имеет свой адрес. Во многих языках программирования, включая Паскаль и Си, адреса считаются информацией, которую можно хранить и обрабатывать; но если при работе на языке ассемблера адреса ничем не отличаются от обычных чисел, то языки высокого уровня вводят для адресов отдельные типы данных. Как и в Паскале, в языке Си адресный тип привязан к типу переменной, адрес которой имеется в виду. Отсюда существуют два базовых принципа, которые формулировали для указателей: Указатель — это переменная, в которой хранится адрес. Утверждение вида «A указывает на B» означает «A содержит адрес B». В предыдущих лекциях, ПЗ и ЛР были введены базовые (основные) типы языка Си. Для их определения и описания используются служебные слова: char, short, int, long, signed, unsigned, float, double, enum, void. В языке Си, кроме базовых типов, разрешено вводить и использовать производные типы, каждый из которых получен на основе более простых типов. Указатели. Введение Стандарт языка Си определяет три способа получения производных типов: массив элементов заданного типа; указатель на объект заданного типа; функция, возвращающая значение заданного типа. Каждая переменная в программе - это объект, имеющий имя и значение. По имени можно обратиться к переменной и получить (а затем, например, напечатать) ее значение. В операторе присваивания выполняется обратное действие - имени переменной из левой части оператора присваивания ставится в соответствие значение выражения его правой части. С точки зрения машинной реализации, имя переменной соответствует адресу того участка памяти, который для нее выделен, а значение переменной - содержимому этого участка памяти. 2 BSS-сегмент (block started by symbol) содержит неинициализированные глобальные переменные, или статические переменные без явной инициализации. Этот сегмент начинается непосредственно за data-сегментом. Обычно загрузчик программ инициализирует bss область при загрузке приложения нулями. Дело в том, что в data области переменные инициализированы – то есть затирают своими значениями выделенную область памяти. Так как переменные в bss области не инициализированы явно, то они теоретически могли бы иметь значение, которое ранее хранилось в этой области, а это уязвимость, которая предоставляет доступ
до приватных (возможно) данных. Поэтому загрузчик вынужден обнулять все значения. За счёт этого и неинициализированные глобальные переменные, и статические переменные по умолчанию равны нулю. Указатели. Введение. Упрощенная структура исполняемого файла Статические данные распределены в специальном статическом сегменте памяти программы Глобальные данные объявленные вне функций. Данные, объявленные внутри функций как static – статические локальные данные: доступны только функции, в которой описаны, но существуют (занимают память) во время выполнения всей программы. Локальные переменные, объявленные внутри функций 1 Мбайт 1 Мбайт Стек – область памяти, в которой хранятся локальные переменные и адреса возврата