-1

私はパスカルに精通しており、このアセンブリ関数で何が問題になっているのか理解できません:

{$ASMMODE intel}
function SomeType.doSomething : boolean; assembler;
var i : integer; // for testing
asm
   mov EAX, field
   mov i, EAX // line 42
   and EAX, 4
   mov i, EAX
    //...
end;

クラスの宣言:

type
    SomeType = class(TObject)
    private
        field : integer;
        function doSomething : boolean;
    // ...
    end;

このメソッドを呼び出す前にfield(クラスのフィールドSomeType) が 4 の場合、IDE (Lazarus) は 42 行目で 8 が割り当てられていることを報告しますi(上記の行番号を参照)。

私が見逃しているインラインアセンブリについて何かありますか?

EAXフィールドの値が正しく保存および/またはロードされないのはなぜですか?

更新: 64 ビットをターゲットにしている可能性があると思います。

4

1 に答える 1

6

オブジェクトのフィールドを読み取ることは、通常のメモリからの読み取りほど単純ではありません。メンバー アクセスは暗黙的に を通過することを思い出してください。したがって、コードSelfを記述するとき、field実際に意味するのはSelf.fieldです。から値を読み取るにはSelf.field、コンパイラは実際にコードを次のようなものに置き換える必要があります。

mov EAX, dword ptr [EAX + offset SomeType.field]

デバッガーで CPU ビューをチェックして、それが実際に起こっているかどうかを確認できます。

そうではないことがわかると思います。Free Pascalが Delphi と同じようにこのコードを解釈する場合、 への裸の参照にfieldは暗黙的なSelf部分が含まれていません。代わりに、クラス内のそのフィールドのオフセットにすぎません。あなたのクラスで宣言された 2 番目のデータ メンバー (祖先クラスで宣言されたものを含む) はありますかfield? もしそうなら、それはあなたがどこから8を得るかを説明しています. VMT ポインターの場合は 0、最初のフィールドの場合は 4 というように、4 バイトを超えるものはなく、すべてが整列されていると仮定します。

上記のコード行のように、メモリから値を読み取るようにコードを変更します。タイプはそこで許可される場合と許可されない場合があります。offset fieldつまり、代わりに と書くだけでもかまいませんoffset SomeType.field

于 2013-08-21T17:47:42.900 に答える