スタンフォードのチュートリアルとGCCの間の競合

elyashiv

このムービー(約38分)によると、同じローカル変数を持つ2つの関数がある場合、それらは同じスペースを使用します。したがって、次のプログラムは、を出力する必要があります5gcc結果とともにコンパイルします-1218960859どうして?

プログラム:

#include <stdio.h>

void A()
{
    int a;
    printf("%i",a);
}

void B()
{
    int a;
    a = 5;
}

int main()
{
    B();
    A();
    return 0;
}

要求に応じて、逆アセンブラからの出力は次のとおりです。

0804840c <A>:
 804840c:   55                      push   ebp
 804840d:   89 e5                   mov    ebp,esp
 804840f:   83 ec 28                sub    esp,0x28
 8048412:   8b 45 f4                mov    eax,DWORD PTR [ebp-0xc]
 8048415:   89 44 24 04             mov    DWORD PTR [esp+0x4],eax
 8048419:   c7 04 24 e8 84 04 08    mov    DWORD PTR [esp],0x80484e8
 8048420:   e8 cb fe ff ff          call   80482f0 <printf@plt>
 8048425:   c9                      leave  
 8048426:   c3                      ret    

08048427 <B>:
 8048427:   55                      push   ebp
 8048428:   89 e5                   mov    ebp,esp
 804842a:   83 ec 10                sub    esp,0x10
 804842d:   c7 45 fc 05 00 00 00    mov    DWORD PTR [ebp-0x4],0x5
 8048434:   c9                      leave  
 8048435:   c3                      ret    

08048436 <main>:
 8048436:   55                      push   ebp
 8048437:   89 e5                   mov    ebp,esp
 8048439:   83 e4 f0                and    esp,0xfffffff0
 804843c:   e8 e6 ff ff ff          call   8048427 <B>
 8048441:   e8 c6 ff ff ff          call   804840c <A>
 8048446:   b8 00 00 00 00          mov    eax,0x0
 804844b:   c9                      leave  
 804844c:   c3                      ret    
 804844d:   66 90                   xchg   ax,ax
 804844f:   90                      nop
Jonathon Reinhart

はい、はい、これは未定義の動作あなたが初期化されていない変数を使用しているので、1

ただし、x86アーキテクチャ2では、この実験は機能するはずです。値はスタックから「消去」されません。また、で初期化されていないためB()、スタックフレームが同一であれば、同じ値が存在するはずです。

内部でint a使用されいないためvoid B()、コンパイラはそのコードを最適化し、スタック上のその場所に5が書き込まれることはなかったと思います。追加してみてくださいprintfB()にも-それだけで動作する可能性があります。

また、コンパイラフラグ(つまり最適化レベル)もこの実験に影響を与える可能性があります。-O0gccに渡して最適化を無効にしてみてください

編集:私はあなたのコードをgcc -O0(64ビット)でコンパイルしました、そして実際、プログラムはコールスタックに精通している人が期待するように5を出力します。実際、それはなくても機能しました-O032ビットビルドは動作が異なる場合があります。

免責事項:Doが今までになく、これまでの「本物」のコードにこのようなものを使用!

1-これが公式に「UB」であるかどうか、または単に予測できないかどうかについて以下で議論が行われています

2-また、x64、およびおそらくコールスタックを使用する他のすべてのアーキテクチャ(少なくともMMUを備えたもの)


それが機能しなかった理由を見てみましょうこれは32ビットで最もよく見られるので、でコンパイルし-m32ます。

$ gcc --version
gcc (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2)

$ gcc -m32 -O0 test.c(最適化を無効にして)でコンパイルしましたこれを実行すると、ガベージが出力されます。

見て$ objdump -Mintel -d ./a.out

080483ec <A>:
 80483ec:   55                      push   ebp
 80483ed:   89 e5                   mov    ebp,esp
 80483ef:   83 ec 28                sub    esp,0x28
 80483f2:   8b 45 f4                mov    eax,DWORD PTR [ebp-0xc]
 80483f5:   89 44 24 04             mov    DWORD PTR [esp+0x4],eax
 80483f9:   c7 04 24 c4 84 04 08    mov    DWORD PTR [esp],0x80484c4
 8048400:   e8 cb fe ff ff          call   80482d0 <printf@plt>
 8048405:   c9                      leave  
 8048406:   c3                      ret    

08048407 <B>:
 8048407:   55                      push   ebp
 8048408:   89 e5                   mov    ebp,esp
 804840a:   83 ec 10                sub    esp,0x10
 804840d:   c7 45 fc 05 00 00 00    mov    DWORD PTR [ebp-0x4],0x5
 8048414:   c9                      leave  
 8048415:   c3                      ret    

Bで、コンパイラが0x10バイトのスタックスペースを予約し、int a変数[ebp-0x4]を5に初期化したことがわかります

ではAただし、コンパイラが置かint a[ebp-0xc]したがって、この場合、ローカル変数同じ場所に配置されませんでした追加することによりprintf()、呼をA、同様のスタックフレームを引き起こしますAB同一である、および印刷します55

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Googleフォーム送信トリガーとスプレッドシート作成の間の競合状態?

分類Dev

ビルド中のCPUとアーチ間の競合

分類Dev

アプリプールの開始モードとアイドルタイムアウトアクションの間に競合はありますか?

分類Dev

ChromeとHyper-Vのデフォルトスイッチ間の競合

分類Dev

HTTP 404:スプリングセキュリティURLフィルターとディスパッチャーサーブレットURLマッピング間の競合

分類Dev

スーパークラスメソッドとインターフェイスのデフォルトメソッドの競合解決

分類Dev

これはRoRチュートリアルテストの競合ですか?

分類Dev

Git-プルリクエスト前のマスターブランチと機能ブランチ間の競合を修正

分類Dev

ヒアドキュメントのベース名の競合?

分類Dev

Symfonyフォームのバンドル間の翻訳の競合

分類Dev

TangoとDjangoのチュートリアル:フォーム

分類Dev

TSLintとVSコードのフォーマットドキュメントの競合

分類Dev

チェックボタンとスケールの競合

分類Dev

参照とプラットフォーム間のVisualStudioの競合

分類Dev

スライドアウトメニューとのステータスバーの競合を修正

分類Dev

Rシャイニーのアクションボタンとのデータテーブルの競合にフォーマットを追加する

分類Dev

Rシャイニーのアクションボタンとのデータテーブルの競合にフォーマットを追加する

分類Dev

フォークとマスターブランチの間でgitの競合を取得するにはどうすればよいですか?

分類Dev

osxユーザーインターフェイスの講義とチュートリアル

分類Dev

リアルタイムとCPU時間のパフォーマンス測定

分類Dev

Androidのピンチズームとビュー間のロングクリックの競合

分類Dev

Androidのピンチズームとビュー間のロングクリックの競合

分類Dev

AkkaHTTPクライアントとAkkaアクターのパフォーマンスチューニング

分類Dev

アップサート(競合時)と書き込み前の読み取りのパフォーマンス

分類Dev

Kubernetes:ローカルフォルダをポッドにマウントする際の問題-「0/1ノードが使用可能です:1ノードでボリュームノードアフィニティの競合が発生しました。」

分類Dev

フレンドスマッシュチュートリアルのchallenge_bragとchallenge_score

分類Dev

reactスクリプトとjestバージョン24.7.1の間の競合

分類Dev

スケジューラのタイムラインでの競合の検出(アルゴリズム)

分類Dev

集約ルートのロジックとパフォーマンスの競合

Related 関連記事

  1. 1

    Googleフォーム送信トリガーとスプレッドシート作成の間の競合状態?

  2. 2

    ビルド中のCPUとアーチ間の競合

  3. 3

    アプリプールの開始モードとアイドルタイムアウトアクションの間に競合はありますか?

  4. 4

    ChromeとHyper-Vのデフォルトスイッチ間の競合

  5. 5

    HTTP 404:スプリングセキュリティURLフィルターとディスパッチャーサーブレットURLマッピング間の競合

  6. 6

    スーパークラスメソッドとインターフェイスのデフォルトメソッドの競合解決

  7. 7

    これはRoRチュートリアルテストの競合ですか?

  8. 8

    Git-プルリクエスト前のマスターブランチと機能ブランチ間の競合を修正

  9. 9

    ヒアドキュメントのベース名の競合?

  10. 10

    Symfonyフォームのバンドル間の翻訳の競合

  11. 11

    TangoとDjangoのチュートリアル:フォーム

  12. 12

    TSLintとVSコードのフォーマットドキュメントの競合

  13. 13

    チェックボタンとスケールの競合

  14. 14

    参照とプラットフォーム間のVisualStudioの競合

  15. 15

    スライドアウトメニューとのステータスバーの競合を修正

  16. 16

    Rシャイニーのアクションボタンとのデータテーブルの競合にフォーマットを追加する

  17. 17

    Rシャイニーのアクションボタンとのデータテーブルの競合にフォーマットを追加する

  18. 18

    フォークとマスターブランチの間でgitの競合を取得するにはどうすればよいですか?

  19. 19

    osxユーザーインターフェイスの講義とチュートリアル

  20. 20

    リアルタイムとCPU時間のパフォーマンス測定

  21. 21

    Androidのピンチズームとビュー間のロングクリックの競合

  22. 22

    Androidのピンチズームとビュー間のロングクリックの競合

  23. 23

    AkkaHTTPクライアントとAkkaアクターのパフォーマンスチューニング

  24. 24

    アップサート(競合時)と書き込み前の読み取りのパフォーマンス

  25. 25

    Kubernetes:ローカルフォルダをポッドにマウントする際の問題-「0/1ノードが使用可能です:1ノードでボリュームノードアフィニティの競合が発生しました。」

  26. 26

    フレンドスマッシュチュートリアルのchallenge_bragとchallenge_score

  27. 27

    reactスクリプトとjestバージョン24.7.1の間の競合

  28. 28

    スケジューラのタイムラインでの競合の検出(アルゴリズム)

  29. 29

    集約ルートのロジックとパフォーマンスの競合

ホットタグ

アーカイブ