Вводятся ли в стек временные значения, такие как операнды арифметических операторов? - PullRequest
0 голосов
/ 25 января 2011

Я хотел бы знать, что происходит в памяти, когда я использую такие арифметические операторы, как:

int i;
i = 5 + 3;

Будут ли значения 5 и 3 автоматически помещаться в стек временно (например, если для них автоматически создаются некоторые статические переменные)? Я полагаю, что они должны где-то существовать, чтобы произошло дополнение, так где?

Что происходит, когда задействован вызов функции?

i = 5 + f(3);

Передается ли аргумент 3 в f где-нибудь? А как насчет возвращаемого значения f (скажем, f возвращает int)?

Большое спасибо,

Ответы [ 5 ]

3 голосов
/ 25 января 2011

Ваш первый пример будет оценен во время компиляции (см. http://en.wikipedia.org/wiki/Constant_folding),, поэтому давайте его проигнорируем.

В случае чего-то вроде i = f(3) + g(5), компилятор имеет много вариантов того, какчтобы реализовать это, в зависимости от конкретной платформы, на которой вы работаете. Это может поместить вещи в регистры, или в стек, или даже в другое место, как он считает нужным.

2 голосов
/ 25 января 2011

Спецификация C не требует, чтобы эти значения были помещены в память. Реализация может хранить их в регистрах и никогда не сохранять их в памяти для выполнения добавления, или компилятор может даже переписать 5 + 3 в 8 и вообще не делать никаких добавлений во время выполнения. Любая реальная реализация делает это так.

В теории языка, фактически, 5 и 3 не относятся к памяти. Они являются значениями (а не просто представляют местоположение, из которого можно извлечь значение). Вы можете легко увидеть это, пытаясь написать &5. Это не сработает - нет адреса, который вы могли бы получить.

1 голос
/ 25 января 2011

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

0 голосов
/ 25 января 2011

Когда у вас есть выражение, такое как i = 5 + 3, нет необходимости помещать операнды в стек.Компилятор переведет это в нечто похожее на:

mov eax, 5                   // load first operand
add eax, 3                   // compute the sum
mov [ebp - 4], eax           // and store it

Операнды жестко закодированы в инструкции.Некоторый компилятор может решить сделать этот код следующим образом: int i = 8.

i = 5 + f(3)

В этом случае 3 будет помещено в стек, потому что f должен быть вызван, но его возвращениезначение (обычно) хранится в eax.Этот код сборки может быть хорошим переводом:

push 3                      // f's argument
call f                      // call f, return value is in eax
add eax, 5                  // compute the sum
mov [ebp - 4], eax          // and save in i
0 голосов
/ 25 января 2011

Компилятор будет распределять временные переменные по мере необходимости. Это делается во время компиляции / оптимизации. Не во время выполнения (для программ на Си, в любом случае). Скорее всего, для вашего примера, результат

5 + 3

или

5 + f(3)

будет сохранено в регистре, а значение регистра будет скопировано в местоположение i.

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