2024年に成し遂げたこと

VC6で以下のようにメモリ上の4バイトは逆さなのでしょうか?
非常に使いづらいです。
正しく?1を取得する方法が知りたいです。

int a[2] = { 1, 2 };

_asm{ // 2003年頃の本を見ると__asmだし、他ではasmだった。 _asmはVC特有?

mov esi, a // メモリ上では 0x01 0x00 0x00 0x00 0x02 0x00 0x00 0x00と逆さに入ってる

mov eax, [esi+0]; // eaxが 0x10000000

// eaxには1が入って欲しいのですが無理なのでしょうか?


普通の感覚から考えてビックエンディアンが良いと思うのですが、
リトルエンディアンは何に便利なのでしょうか?

A 回答 (7件)

やりたいことを Cで記述しその部分にブレークポインタを設定、実行します



ブレークしたら 表示 > デバッグウィンドウ > 混合モード
で アセンブラコードとソースが一度に参照できます
コンパイラがどのようなコードを吐いているの確認してみましょう

ポインタなら その中身は何処かのアドレスを挿しています
引数の配列なら Cではポインタで渡されます
mov命令でレジスタに設定できます

リスティングファイルでアセンブラファイルを作ってしまうなんて方法もあります
プロジェクト > 設定 > C++タブ > カテゴリ-> リスティングファイル
で設定できます
    • good
    • 0

#3のzwiです。



>x自体がポインタだからと思います。
>そう理解してよいでしょうか?

そうです。
mov esiは、メモリから値(この場合はポインタ値)をesiレジスタにロードする命令です。
lea esiは、アドレスを計算してesiレジスタにロードする命令です。
ポインタの場合は上記を、変数を直接参照する場合は下記の命令を使います。

ここで例を挙げてみます。
int a[2];
と書かれていた場合と
int b[2];
int *a = b;
と書かれた場合ですが、C言語での値の取り出しはどちらもa[0]で取り出せますよね。
しかしアセンブラでは違いを意識しないといけません。
a変数からアクセスをする場合、上記はlea、下記はmovを使うことになります。
    • good
    • 0

ビッグとリトルが逆に見えるというのは人の都合でしかありません。


ハードから見れば同じに見えます。
そう思えばたいした問題ではありません。
失礼ながら、質問内容がバグっているような気もしますが・・・。
    • good
    • 0
この回答へのお礼

現場の方、コメントありがとうございます。
目から鱗でした。

>失礼ながら、質問内容がバグっているような気もしますが・・・。

いつも半分、そうです。(^^;

お礼日時:2007/10/19 14:26

リトルエンディアン:ビッグエンディアンよりすぐれた方式。


ビッグエンディアン:リトルエンディアンよりすぐれた方式。
    • good
    • 1
この回答へのお礼

回答ありがとうございます。
直ぐに理解できませんでした。
今度から平易な内容でお願いいたします。

お礼日時:2007/10/19 14:28

リトルエンディアンのメリットですか?


そもそもは設計思想の違いとしか言いようが無いですね。
リトルエンディアンは、小さい桁の数値を小さいアドレスから書くべきだという考え方で設計されています。これはソフト的な思想ではなくハード設計者の思想です。
一度そういう思想で設計しちゃったら同じ会社でCPUを作る限り続けるしかないわけです。前のCPUで作ったデータの読み書きで困りますからね。インテルだと初期の8ビットCPUの8008がそういう設計思想でした。そこから今の64ビットCPUまで延々と続いているんです。

特徴としては、元の格納データサイズを知らずにデータを取り出せることでしょうか?
例えば、0x12345678という値はメモリ上では、
0x78 0x56 0x34 0x12
と格納されています。
下位1バイトを取り出すと、0x78と言う下位データが取り出せます。
下位2バイトを取り出すと、0x5678と言う下位2バイトのデータが取り出せます。
これはビックエンディアンでは、元々の格納長を知らなければ取り出せません。4バイトと知っていて始めて取り出せるのです。
何に使えるか?って聞かれると困るんですけどね(^^ゞ
    • good
    • 0
この回答へのお礼

為になります。

お礼日時:2007/10/19 14:55

インテル系x86 CPUでしたら


esiが配列 aを取得できているのであれば
mov eax,[esi+0];
で eaxは 1が格納されます

ただ mov命令で esiに 配列aの先頭アドレスを取得できません
やるなら leaなどのLoad系の命令を使います

lea esi, a;
といった具合です
    • good
    • 0
この回答へのお礼

>ただ mov命令で esiに 配列aの先頭アドレスを取得できません
>やるなら leaなどのLoad系の命令を使います

大域変数の場合、
lea esi, a
でうまくいきました。

関数で配列のポインタを使う場合
void test(const int x[])
の場合は、
mov esi, x
でないと、うまくいきません。
x自体がポインタだからと思います。
そう理解してよいでしょうか?

最初の1が取得できない件は、指すアドレスが間違っていて、たまたま指しているデータが0x1000000でした。すみませんでした。

お礼日時:2007/10/15 22:39

ん? eax って 0x10000000 になりますか? 1 になるような気がするんだけど....

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報