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 命令保存为字符串并使用 mixin 怎么样?

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);
}

另一种选择是使用混合来创建整个函数,并将其签名和 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

模板 mixins 只能包含声明(如此处所指定)。如果要插入任意代码,则需要字符串混合:

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 回答