1

私がコンパイルした場合:

int *a;

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

次に、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 は pointersproject!a によって記号化されます。すべて良い。

ただし、メイン内でポインターを宣言すると、次のようになります。

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 Debugging: Practical Foundations を見ながら考えたことに触発されました)。

4

1 に答える 1

4

変数が関数内で定義されている場合、明示的に static と宣言されていない限り、その変数は自動変数です。このような変数は、関数の実行中にのみ存在し、通常はスタックに割り当てられるため、関数が終了すると割り当てが解除されます。コンパイルされたコードに見られる変更は、スコープの変更によるものではなく、静的変数から自動変数への変更によるものです。static を作成すると、そのスコープが関数 main であっても、スタックに割り当てられません。

于 2011-05-18T17:58:14.763 に答える