1

私はコードのチャンクをMASMからCインラインアセンブラ(x86、Windows、MS VC)に移植しています。Foolowingは実際のコードではなく、単なるアイデアを与えるためのなりすましです。静的配列または2つのラベル間のコードチャンクとして定義されたデータがあり、そのサイズを取得する必要があるとします。

    label1:
    bla bla bla
    label2:
    ....
    mov eax, (offset label2 - offset label1)

このようなコードは、MASMではチャームのように機能しますが、CIでは次のエラーメッセージが表示されます。「エラーC2425:'-':'第2オペランド'の非定数式」コンパイルできます:

    mov eax, offset label1
    mov eax, offset label2

コンパイラがコンパイル時に(offset label1-offset label2)を評価することを期待していますが、間違っているようです。オフセットも追加できません(なぜですか?これらはコンパイル中に追加された2つの整数です...?)確かに、mov eax、offset label2 mov edx、offset label1 sub eax、edxをコンパイルできますが、それは余分なコードです定数を計算するためだけに。誰かが私に説明してもらえますか、私のコードの何が問題になっていますか?

引っ越しによるものでしょうか?どのようにそれを押し通すのですか?

回答をお待ちしております、ありがとうございます。

4

2 に答える 2

0

実際のアセンブラは、すべてのラベルの固定アドレスを取得する前に、おそらく数回のパスでコードを実行しています。たとえば、ジャンプの距離に応じて、短い形式と長い形式のジャンプがあります。ラベル間にそのようなジャンプがある場合、距離はジャンプがどこに行くかによって異なります。

Cコンパイラは、その一部をリンカ/ローダーに任せ、コンパイル時に値が修正されない場合があります。

addres計算コードを2つの命令にまで下げることができます

mov EAX, offset Label2
sub EAX, offset Label1

これがコードのパフォーマンスを正確に損なうとは思わない。

于 2012-11-16T16:56:07.150 に答える
0

はい、それは再配置の脅威によって引き起こされる可能性がありますが、相対ジャンプを処理する可変長命令の脅威によっても引き起こされる可能性があります。おそらくいくつかの小さな問題が原因で、アセンブラーの作成者は簡単な方法を取り、できるだけ早く最終決定を行う1パスまたは2パスのコンパイラーを実装しました。したがって、いくつかの便利な式はサポートされていません。

コメントですでに示唆されているように、アセンブラはおそらくmov+subの組み合わせをサポートしています。

于 2012-11-16T17:04:44.440 に答える