Нет, он не может знать значение esp
заранее.
Возьмем, к примеру, рекурсивную функцию, т.е.функция, которая вызывает себя.Предположим, что такая функция имеет несколько параметров, которые передаются через стек.Это означает, что каждый аргумент занимает некоторое место в стеке, тем самым изменяя значение регистра esp
.
Теперь, когда функция введена, точное значение esp
будет зависеть от того, сколько разфункция вызывала себя ранее, и компилятор не мог знать об этом во время компиляции.Если вы сомневаетесь в этом, возьмите такую функцию:
void foobar(int n)
{
if (rand() % n != 17)
foobar(n + 1);
}
Компилятор не сможет быть настолько умным, чтобы заранее определить, вызовет ли функция себя еще раз.
Если компилятор хотел определить esp
заранее, ему фактически пришлось бы создать версию функции для каждого возможного значения для esp
.
Приведенное выше объяснение учитывает только одну функцию.В реальном сценарии программа имеет много функций, которые взаимозависимы друг с другом, что приводит к довольно сложным «графам вызовов».Это вместе с (помимо прочего) непредсказуемой программной логикой означает, что компилятору придется создавать огромный массив версий каждой функции, просто для оптимизации на esp
- что явно не имеет смысла.
PS: Теперь что-то еще.На самом деле вам вообще не нужно оптимизировать [esp+N]
, потому что это не должно занимать больше процессорного времени, чем простое [esp]
... по крайней мере, на процессорах Intel Pentium.Можно сказать, что они уже содержат оптимизации именно для этого и даже более сложных сценариев.Если вам интересны процессоры Intel, я предлагаю вам поискать документацию для чего-то, что называется MOD R / M и SIB байт машинной инструкции, например, здесь для байта SIB или здесь или, конечно, в официальной документации Intel для разработчиков ЦП.