2016-05-14 4 views
0

Clang/LLVM(Apple LLVMバージョン6.1.0(clang-602.0.49) 対象:x86_64-apple-darwin14.3.0)でコンパイルすると、以下のCコードが出力されます。私は実際にC標準私はラベルを作る方法があるかどうかを知りたいのですが、そこから-8バイトのオフセットが自分の選択した別のクワッドワードがあるようにします。私はそれをMac OS XとLinuxで動作させたいと思います。__DATAラベルの相対アドレスについて保証はありますか?

#include<stdio.h> 

long long x = 22; 
long long y = 33; 

int main(void) { 
    long long diff = *(&y - 1); 
    printf("%lld\n",diff); 
} 

とDATAセクションの関連部分があります。

.section __DATA,__data 
    .globl _x      ## @x 
    .align 3 
_x: 
    .quad 22      ## 0x16 

    .globl _y      ## @y 
    .align 3 
_y: 
    .quad 33      ## 0x21 

答えて

2

コンパイラは静的/グローバルオブジェクトを任意の順序で自由に配置できます。関数と同じです。コンパイラは、キャッシュフットプリントを減らすために、 "ホット"または "コールド"データまたは関数をグループ化しようとする可能性があります。

1つの基本ポインタから複数のものを参照する場合は、それらを構造体または配列に配置します。 @kcraigieがコメントで示唆するように、配列と構造体の間にunionが可能です。 (しかしおそらく役に立たないでしょう)。

メモリ内の配列レイアウトは保証されています。 structレイアウトにもいくつかの保証がありますが、コンパイラが期待しない場所にパディングを置くことを禁じることはできません。ただし、同じプラットフォーム上で同じABIをターゲットとするすべてのコンパイラと同じ構造体レイアウトに依存することができます。

メモリ内のレイアウトを本当に気にしている場合は、enum、またはGLOBAL_Xからglobal_array[0]などを定義するマクロを使用して、異なる配列要素に記号名を付けることができます。それ以外の場合は、structを使用してください。グループ化する目的がブロックとしてコピーできるのであれば、うまくいきます。


@kcraigieの答えとは逆に、メモリブロックを動的に割り当てる必要はありません。静的配列または構造体は、ジョブをうまく処理します。明らかに、静的ストレージは不要な場合は無駄です。可能であれば自動(スタック)ストレージを使用してください。


再:コメントでの質問:

ようなデータセクションに置かれた場合、アセンブラは、右隣りにそれらを保ちますか?

はい。アセンブラはバイトをオブジェクトファイルにアセンブルするだけで、の部分をに移動するスコープはありません。 .alignディレクティブではギャップが発生する可能性がありますが、xとyの間の.alignは(xの前の.alignのため、すでに8バイト境界に設定されているため)0バイトに拡張されます。

異なるセクション(.text/.rodata.dataとカスタムセクション)は、リンク時にのみ最終的な順序に入れられます。

0

sane Cコンパイラはすべて連続したメモリに配置する必要がありますが、保証されていません。 AFAIKは、自分自身をスタックまたはヒープ(またはグローバル)に割り当てることができる唯一の方法ですが、連続したメモリが保証されます。

+1

グローバルセクションはスタックでもヒープでもないデータセクションに移動しますか? –

+0

ああ、ありがとう。私の答えを修正しました。 – kcraigie

+0

アセンブラは、そのようなデータセクションに配置されている場合は、アセンブラはそれぞれのすぐ隣に置かれますか? –

関連する問題