Базовый cdb: изменяется ли cdb в зависимости от области видимости? - PullRequest
1 голос
/ 18 мая 2011

Если я скомпилирую:

int *a;

void main(void)
{
    *a = 1;
}

и затем разбираю main в cdb получаю:

pointersproject!main:
00000001`3fd51010 mov     rax,qword ptr [pointersproject!a (00000001`3fd632f0)]
00000001`3fd51017 mov     dword ptr [rax],1
00000001`3fd5101d xor     eax,eax
00000001`3fd5101f ret    

Так что * a символизируется указателем проекта! A. Все хорошо.

Однако, если я объявлю указатель внутри main:

void main(void)
{
    int *a;
    a = 1;
}

Я вижу, что a - это просто смещение от указателя стека (я полагаю), а не от понятной человеку структуры, которую я ожидал (например, pointersproject! Main! A):

pointersproject!main:
00000001`3fd51010 sub     rsp,18h
00000001`3fd51014 mov     rax,qword ptr [rsp]
00000001`3fd51018 mov     dword ptr [rax],1
00000001`3fd5101e xor     eax,eax
00000001`3fd51020 add     rsp,18h
00000001`3fd51024 ret

Это, вероятно, в моем понимании того, что сделал компилятор, так же, как и все остальное, но: кто-нибудь может объяснить, почему нотация для a не то, что я ожидаю?

(Это вдохновлено размышлениями при взгляде на отладку Windows x64: практические основы Дмитрия Востокова).

1 Ответ

4 голосов
/ 18 мая 2011

Когда переменная определена внутри функции, она является автоматической переменной, если явно не объявлена ​​как статическая. Такие переменные существуют только во время выполнения функции и обычно размещаются в стеке, поэтому они освобождаются при выходе из функции. Изменения, которые вы видите в соответствующем коде, связаны не с изменением области действия, а с изменением статической переменной на автоматическую. Если вы создадите статический объект, он не будет размещен в стеке, даже если его область действия - функция main.

...