我刚刚在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();
}
在C中我会做这样的事情
#define STARTASM() asm{.......}
但如果我尝试这样的话
template endtemplate()
{
asm{mov EBX, ip;add ip,4;jmp dword ptr [EBX];db END_KEY;}
}
它会抛出一个错误,说我必须在模板上声明一个变量(我不想这样做,因为这里绝对需要性能)。
答案 0 :(得分: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);
}
另一种选择是使用混合来创建整个函数,并将其签名和内容(= 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*/
})());
答案 1 :(得分:1)
模板mixins只能包含声明(as specified here)。如果你想插入任意代码,你需要字符串mixins:
enum startTemplate = "asm{...}";
enum endTemplate = "asm{...}";
__gshared void jump()
{
mixin(startTemplate);
...etc...
mixin(endTemplate);
}
您可以使用此机制插入可以使用简单D函数(executed at compile time by the compiler!)生成的自定义程序集:
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));
}