Как имена / адреса памяти переменных представлены на уровне битов? - PullRequest
5 голосов
/ 31 января 2012

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

Допустим, ради аргумента, я говорю о кодировании в C ...

Я понимаю, что (системно-зависимый) int занимает 4 байта или 32 бита памяти.

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

например. int myInt = 5;

Мой вопрос - как и где адрес памяти и имя переменной представлены на уровне битов? При компиляции кода компилятор в основном говорит: «Хорошо, myInt ссылается на адрес 0xffffff» и по существу заменяет адрес памяти в машинном коде? Даже если бы это было так, я все еще не понимаю, как представлен адрес памяти ...

Я надеюсь, что мое замешательство достаточно ясно!

Ответы [ 2 ]

4 голосов
/ 31 января 2012

Теоретически, ответ "это зависит от реализации" . Каждый компилятор C выбирает лучший подход - пока он демонстрирует правильное поведение, не имеет значения, как вы туда попали.

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

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

  • Для локальных переменных, как часть процесса компиляции, компилятор заменяет имя каждой переменной (например, «int foo;») ссылкой на соответствующую память, выделенную для этой переменной («адрес памяти 0x482c»). Назначения или ссылки на это значение обычно могут просто ссылаться на соответствующий адрес.

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

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

В некоторых случаях полезно включать имена переменных в выходные данные компилятора, например при отладке. В этих случаях создается таблица символов отладки . Это способ сопоставления адресов с именами , которые являются значимыми для людей, так что при возникновении сбоя вы можете увидеть «Stacktrace: function foo () ...» вместо «» Stacktrace: адрес памяти 0x4572 ... ".

В языках с возможностями метапрограммирования, таких как C #, Ruby или Java, имена часто становятся частью метаданных, которые хранятся вместе с объектом, а не просто заменяют каждую ссылку поиском в памяти адрес. Эти метаданные пригодятся, когда вы захотите сделать некоторые аккуратные трюки, которые практически невозможны в C во время выполнения, например, запросить «у каких объектов в этой коллекции есть поле с именем foo?».

1 голос
/ 31 января 2012

При компиляции кода компилятор в основном говорит: «Хорошо, myInt ссылается на адрес 0xffffff» и по существу заменяет адрес памяти в машинном коде?

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

Если myInt имеет глобальную или файловую область, он остается myInt до тех пор, пока компоновщик не сможет выбрать абсолютное местоположение.

Я все еще не понимаю, как представлен адрес памяти ...

Байты в памяти нумеруются по возрастанию. Таким образом, абсолютный адрес или смещение стека оба выглядят как int на уровне битов.

...