1

如果我编译:

int *a;

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

然后在 cdb 中反汇编 main 我得到:

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 由 pointersproject!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 的符号不是我所期望的?

(这灵感来自于 Dmitry Vostokov 在查看 x64 Windows 调试:实用基础时的沉思)。

4

1 回答 1

4

在函数内部定义变量时,除非显式声明为静态变量,否则它是自动变量。此类变量仅在函数执行期间存在,并且通常在堆栈中分配,因此它们在函数退出时被释放。您在编译的代码中看到的变化不是由于范围的变化,而是由于从静态变量到自动变量的变化。如果你做一个静态的,它不会被分配到堆栈中,即使它的作用域是函数 main。

于 2011-05-18T17:58:14.763 回答