2012-02-19 8 views
10

私は自分自身を明確にしていないことを理解します。C++コンパイラはどのように変数名をコンパイルしますか?

実行ファイル(マシンコード)では、どのように "変数"が表現されていますか?彼らは静的なメモリアドレスですか?コンパイラは各自に特定の "名前"を与えますか(またはあなたが与えたものだけを保持しますか?)コードで表すと

それぞれのプログラムを行い、すべてのマシンは、値5を保持するためにinputed値を保持するために、それは今保持している値に1を追加しようとしているアドレスを知っているどのように
int x=5; 
//Bunch of code 
cin>>y; 
cout<<x+1; 

最後に同じ値を印刷します。

--João

答えて

6

は、C言語で簡単なプログラムです:

int main() { 
    int a = 5; 
    int b = 7; 

    int c = a + b; 

    return 0; 
} 

あなたがLinuxでgcc -m32 -S -O0 -o main.s main.cでコンパイルした場合は、この場合には、見ることができるように、あなたはこの

.file "main.c" 
    .text 
    .globl main 
    .type main, @function 
main: 
.LFB0: 
    /* %ebp is a Base Pointer Register */ 
    pushl %ebp 
    movl %esp, %ebp 

    /* Here we reserve space for our variables */ 
    subl $16, %esp 

    /* a's address is %ebp - 4 */ 
    movl $5, -4(%ebp) 

    /* b's address is %ebp - 8 */ 
    movl $7, -8(%ebp) 

    /* a + b */ 
    movl -8(%ebp), %eax 
    movl -4(%ebp), %edx 
    addl %edx, %eax 

    /* c's address is %ebp - 12 */ 
    movl %eax, -12(%ebp) 

    /* return 0 */ 
    movl $0, %eax 
    leave 
    ret 

ような何かを得るでしょう変数のアドレスは、関数の基本ポインタのオフセットとして計算されます。最適化を有効にすると、変数の値がレジスタに格納されます。

+0

ありがとうございます。あなたは私の内部asmコードを説明する手間を経た。あなたは私の質問に答えるだけでなく、私の好奇心を満たし、私が組立を学びたいと思った。あなたに誇りを持ってください。 –

+0

あまりにも多くのことを求めていないのであれば、ちょっとだけ。これらのオフセットは、例えば以下のような意味を持っています:%ebp -12 =基本アドレスから数えて12アドレス少なくなりますか? –

+0

@JoãoSilva%ebpが0xffffcfe8の場合、cのアドレスは0xffffcfe8-4 = 0xffffcfdcとなります。 – kharvd

7

実装固有です。

通常、変数の場所はあらゆる種類の要因と最適化に基づいています。 RAM内に完全に存在するように最適化されているか、または完全に最適化されているため、RAMにはまったく存在しない可能性があります。

実行時に変数名が存在しません。コンパイル中に破棄されます。ただし、コンパイラは、アプリケーションバイナリに格納されているデバッグ情報を発行して、開発者がアプリケーションをデバッグできるようにすることがあります。しかし、これは通常、リリース版では削除されます。

Gamesharkの詳細についてはわかりません。しかし、多くの場合、特定の変数の位置は、アプリケーションのマシンコードを見て把握することができます。

+0

投稿全体が表示されませんでした。ごめんなさい。変数について:コンパイラはどのようにvar名を扱いますか?チートについてデータベースの質問:機械コードによって変数の位置が分かりますか?変数には常に同じアドレスが与えられますか? –

+0

@JoãoSilva:元の質問は本当に意味をなさないが、コンパイラは「変数名をコンパイルしない」。私の答えは、私があなたが知りたいと思うものを説明する試みです。 –

+0

@JoãoSilvaコンパイラは変数名を捨てます。 –

1

だから、これには2つの部分があり、私はベストを尽くします。

コンパイルすると、コンパイラはC++コードを内部表現に変換します。これは、できるだけ効率的にCPUのレジスタを使用し、残りのデータをRAMにプッシュすることに変換されます。プログラムが実行されると、RAMからのデータがレジスタに前後にコピーされます。

他の質問では、私がこの方法で使用している方法の1つは、ユーザーが持つ金のためです。プログラムは、ゲームのメモリ空間全体をコピーしてコピーすることができます。次に、ユーザーは金を得るか失うか(最小限のアクション)を行います。その後、外部アプリケーションは、変更された値と元の金の金額と現在の金の金額をメモリ空間全体で検索します。この場所が見つかると、メモリの場所を編集し、必要な値で更新することができます。

一般的に、ゲームが複雑であるほど、その方法は難しくなります。ここで

+0

ありがとうございます。混乱させて申し訳ありませんが、これを想像してください:int a = 5; a = 6;最初の説明は、プログラムがどの値を変更するかを知っているわけではありません。一方、2番目の答えは、cheatengineのようにメモリ内の値を検索するプロセスを説明しています。私はすでに知っていた。私の質問は、プログラムが実行されるたびに常に同じアドレスが同じ変数を任意のコンソール(ビデオゲームコンソール)に保持しているかのように、アドレスのようなものを保持するチートデータベースに関するものでした。申し訳ありませんが私は明確ではない場合。私の英語はただの助けにはならない。 –

+0

@JoãoSilva:多くのシステムがそれを困難にする[ASLR](http://en.wikipedia.org/wiki/Address_space_layout_randomization)を実装しています。 –

関連する問題