1

Dプログラミング言語のテンプレートのドキュメント全体を読んだだけですが、非常に単純なタスクの方法が見つからないようです。関数については、各関数の先頭に3つのアセンブラ命令を挿入する必要があります。これを自動化したいと思いますマクロなので、毎回手動で記述する必要はありません。

__gshared void jump()
{
    asm{db START_KEY;}

    //bla bla bla

    asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
}

このようなものは

__gshared void jump()
{
    mixin starttemplate();

    //bla bla bla

    mixin endtemplate();
}

CIでは、このようなことをしたでしょう

#define STARTASM() asm{.......}

しかし、私がこのようなことをしようとすると

template endtemplate()
{
    asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
}

テンプレートで変数を宣言する必要があるというエラーがスローされます(ここではパフォーマンスが絶対に必要なので、これはしたくありません)。

4

2 に答える 2

2

asmコマンドを文字列として保存し、ミックスインを使用するのはどうですか?

immutable string ASM_START=q{
    asm{db START_KEY;}
}
immutable string ASM_END=q{
    asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
}

__gshared void jump()
{
    mixin(ASM_START);
    //bla bla bla
    mixin(ASM_END);
}

もう1つのオプションは、ミキシングを使用して関数全体を作成し、その署名とcontent(= body)を引数として渡すことです。

string functionWithAsm(string signature,string content)(){
    return Format!(q{
        %s
        {
            asm{db START_KEY;}
            %s
            asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
        }
        },signature,content);
}

mixin(functionWithAsm!("__gshared void jump()",q{
            /*some actual code*/
            })());
于 2012-07-16T20:30:29.717 に答える
1

テンプレート ミックスインには、宣言のみを含めることができます (ここで指定されているとおり)。任意のコードを挿入したい場合は、文字列 mixin が必要です:

enum startTemplate = "asm{...}";
enum endTemplate = "asm{...}";

__gshared void jump()
{
    mixin(startTemplate);
    ...etc...
    mixin(endTemplate);
}

このメカニズムを使用して、単純な D 関数で生成できるカスタマイズされたアセンブリを挿入できます (コンパイル時にコンパイラによって実行されます! )。

string customAsm(string param1, bool param2)() @property
{
    string ret = "asm{";

    // append to ret, building up some code

    return ret ~ "}";
}

void myfunc()
{
    mixin(customAsm!("foo", false));
}
于 2012-07-16T20:25:14.887 に答える