Вот реальный ассемблерный код, который генерирует VC++ 6.0 на твою функцию
int& Fn()00401560 push ebp
00401561 mov ebp,esp
00401563 sub esp,44h
00401566 push ebx
00401567 push esi
00401568 push edi
00401569 lea edi,[ebp-44h]
0040156C mov ecx,11h
00401571 mov eax,0CCCCCCCCh
00401576 rep stos dword ptr [edi]
6: int i = 20;
00401578 mov dword ptr [ebp-4],14h
7: return i;
0040157F lea eax,[ebp-4]
8: }
00401582 pop edi
00401583 pop esi
00401584 pop ebx
00401585 mov esp,ebp
00401587 pop ebp
00401588 ret
Начало и концовка почти у всех функций стандартна.
Все статические переменные, которые иницилизируются внутри функций, размешаются в стэке. Что илюстрируют данные команды. При этом сам стэк откатывается вниз на длину блока статических переменных.
00401561 mov ebp,esp
00401563 sub esp,44h
Доступ ко всем переменным осушествляется через регистр ebp.
Пример
6: int i = 20;
00401578 mov dword ptr [ebp-4],14h
Блок статических переменных иницилизируется числом 0xCCCCCCCC
00401569 lea edi,[ebp-44h]
0040156C mov ecx,11h
00401571 mov eax,0CCCCCCCCh
00401576 rep stos dword ptr [edi]
Теперь, когда ты выходиш из функции, стэк остаётся на прежней позиции, что и была до входа в функцию.
00401585 mov esp,ebp
00401587 pop ebp
00401588 ret
Но память осталась проиницилизированной числом 20. Теперь до следуюшего запуска любой функции в твоем процессе, память будет содержать это число. После запуска, уже никто не сможет гарантировать, что там будет