tokyo_kyoto_ さんが書きました:
実際のところ、名前aと値123は別々のアドレスの場所に保存されていますし、この点いまいちわかりません。
最初、上の文章が何を言っているのかさっぱり分かりませんでしたが
おそらく、&aで返されてきたアドレスの値とメモリビューア等で確認したときの7bHの格納されている位置で場所にズレがある、的な話をされてるんでしょうね。(ただ、実際はIntel製のCPUのバイトオーダーはリトルエンディアンなので&aのアドレスのbyteに7bが入っていて、7b 00 00 00 となっているはずですが)
それを前提として話をします。
以下の2つは同じことを表現していますが
コード:
_a$ = -4 ; size = 4
mov DWORD PTR _a$[ebp], 123 ; 0000007bH
コード:
mov DWORD PTR [ebp-4], 7bH
重要なことは、即値をメモリへストアする際は、場所とサイズの指定が必要であるということです。
PTR演算子の前にDWORDという単語がありますが、これは4byteを表しています。
つまり、仮想メモリの[ebp-4]の場所から4byte分の広さを使用して7bHという値を格納(保持)してください、という意味です。(具体的には、[ebp-4]から4byteを使用して0000007bH が表現できればいい)
メモリでは1つのアドレスが示す先には、1byte分のサイズの領域しか存在しません。
なので、1つのアドレスが示す先に、宣言した変数毎に色んな明確なサイズの領域がぶら下がってるわけではありません。
そのため、その場所から何byte分(言い換えると何アドレス分)を1つの変数としてみなして使用することにするのかというサイズの指定が重要となります。
int a の &a が 0x0073f8d8 のアドレスを指していたら、int a = 123; (0000007bH)は、以下のように仮想メモリへと格納されます。
コード:
0x0073f8d8 7b
0x0073f8d9 00
0x0073f8dA 00
0x0073f8dB 00
int a という宣言は、結果的にディスプレースメントで確保するサイズが4であることを示しています。そのため
などというエイリアスになっています。
movによるデータのストアで、オフセットアドレスに使用できるレジスタは決まっています。ebpはその内の1つです。
ebpは関数呼び出し時のスタック領域のベースアドレスとして使用されます。
つまり、変数 a はmain関数で使用されているスタック領域に[ebp-4]の位置から4byte分のサイズで確保されたことになっている、ということになります。(4byteのサイズを超過して書き込むこともできてしまう)
レジスタは1つ1つのサイズが決まっていますが、メモリは場所こそ指定できるもののサイズは決まっていません。(また、即値のサイズも決まっていない)
メモリへストアする際にサイズの指定が重要となるのはこのためです。