2012-02-14 8 views
0

分岐テーブルについて質問があります。アセンブラの分岐テーブル(Nasm)

、このようなテーブルを宣言するために2つの方法があります:コードセクタのデータセクター(DS)

  • (CS)
  • いただきまし異なるこの方法の間で

    1. は?

      私はこの次の例を学びました: ケース1:

      SECTION .data 
      i   dd  2; 
      stab   dd  m1,m2,m3 ; branchtable for switch 
      
      SECTION .text 
      global  start 
      start: 
      mov ebx , [ i ]   ;  switch (i) 
      cmp ebx , 1 ; 
      jl end 
      cmp ebx , 3 
      jg end 
      shl ebx , 2 ;  /∗ stab 4 Bytes ∗/
      jmp [ stab+ebx −4];  
      m1: ;do something..... 
      .... 
      

      ケース2: は、私たちの教授は、私たちに語った

      SECTION .data 
      i   dd  2; 
      
      SECTION .text 
      global  start 
      start: 
      mov ebx , [ i ]   ;  switch (i) 
      cmp ebx , 1 ; 
      jl end 
      cmp ebx , 3 
      jg end 
      shl ebx , 2 ;  /∗ stab 4 Bytes ∗/
      jmp [ cs : ebx+stab −4]; branchtable in codesegment 
      ALIGN 4 ;  
      stab   dd  m1,m2,m3 
      m1: ; do something 
      .... 
      

      、その方法2がよりeffectivが、なぜ?分岐テーブルには短いジャンプしかないので、DSに表示する必要はありませんか?

      greetz運命より効果的である方法

    +3

    2番目のケースでは、キャッシュはすでにstabというテーブルを含むメモリ位置をプリフェッチしている可能性が高いためですか? –

    +1

    Peterと同じように、私はキャッシュのローカリティと関係があると思いますが、難しい事実はありません。しかし、私が見た(多くの)コンパイラ生成コードは、常にコードセグメントにジャンプテーブルを持っていたと言えます。 –

    +0

    ああ、スタブの内容をキャッシュした 'align'を実行するので、唯一の効果がありますか? – destiny

    答えて

    2

    しかし、私はあなたの教授に不賛成、あなたが扱っているプロセッサに依存し、CSを使用すると、このように長いと、コードが大きくなって、セグメントプレフィックスオーバーライドが必要ですプロセスが少なく、キャッシュが少ない。 x86ウィンドウ(ユーザランド)ではCSDSが同じリニアアドレス空間にフラット化され、最適な最適化が行われます。 FSGSから離れてすべてのセグメントが無視されるようにx64の下で、これは離れて落ちるもののセグメントベースは、非ゼロである場合

    特定のプロセッサ(インテルAtom)も起因し、(そのベースは暗黙的に0である)CSに遅いアクセスを有しますx64のフラット・アドレッシング・モデル インテルは、セグメント・レジスタをできるだけ少なく使用するようにアドバイスしています(これにより、レジスタ・リネーマーの負担が軽減されます)。

    +0

    素晴らしいコメントをありがとう – destiny