C++ ARM系统调用为c++;模板

C++ ARM系统调用为c++;模板,c++,templates,arm,inline-assembly,system-calls,C++,Templates,Arm,Inline Assembly,System Calls,我需要在我的newlib存根中调用一些系统调用,当前的实现使用的是C宏,随着时间的推移,这些宏变得不可读,外观也很糟糕。(我讨厌宏…) 但是,我用C++模板实现的只对一个参数工作: template <int nr, typename RETTYPE, typename PARAM1> inline RETTYPE syscall(PARAM1 p1) { register PARAM1 r0 asm("r0") = p1; asm volatile("svc %[

我需要在我的newlib存根中调用一些系统调用,当前的实现使用的是C宏,随着时间的推移,这些宏变得不可读,外观也很糟糕。(我讨厌宏…) 但是,我用C++模板实现的只对一个参数工作:

template <int nr, typename RETTYPE, typename PARAM1> 
    inline RETTYPE syscall(PARAM1 p1)
{
  register PARAM1 r0 asm("r0") = p1;
  asm volatile("svc %[nr]\n"
    : "=r" (r0)
    : [nr] "i" (nr), "r" (r0)
    : "memory", "r1", "r2", "r3", "r12", "lr");
  return (RETTYPE) r0;
}
模板
内联RETTYPE系统调用(参数1 p1)
{
寄存器PARAM1 r0 asm(“r0”)=p1;
asm易失性(“svc%[nr]\n”
:“=r”(r0)
:[nr]“i”(nr),“r”(r0)
:“内存”、“r1”、“r2”、“r3”、“r12”、“lr”);
返回(RETTYPE)r0;
}
现在我可以使用

void *ptr = syscall<SYS_MALLOC, void*>(0x1000);
void*ptr=syscall(0x1000);
分配0x1000字节

我的四个参数的实现:

template <int nr, typename RETTYPE, typename PARAM1, typename PARAM2, typename PARAM3, typename PARAM4> 
    inline RETTYPE syscall(PARAM1 p1, PARAM2 p2, PARAM3 p3, PARAM4 p4)
{
  register PARAM1 r0 asm("r0") = p1;
  register PARAM2 r1 asm("r1") = p2;
  register PARAM3 r2 asm("r2") = p3;
  register PARAM4 r3 asm("r3") = p4;

  asm volatile("svc %[nr]\n"
    : "=r" (r0)
    : [nr] "i" (nr), "r" (r0), "r" (r1), "r" (r2), "r" (r3)
    : "memory", "r12", "lr");

  return (RETTYPE) r0;
}
模板
内联RETTYPE系统调用(参数1 p1、参数2 p2、参数3 p3、参数4 p4)
{
寄存器PARAM1 r0 asm(“r0”)=p1;
寄存器PARAM2 r1 asm(“r1”)=p2;
寄存器参数3 r2 asm(“r2”)=p3;
寄存器参数4 r3 asm(“r3”)=p4;
asm易失性(“svc%[nr]\n”
:“=r”(r0)
:[nr]“i”(nr)、“r”(r0)、“r”(r1)、“r”(r2)、“r”(r3)
:“内存”、“r12”、“lr”);
返回(RETTYPE)r0;
}
不起作用,“swi”指令中寄存器的内容是任意的。 不知何故,GCC不再尊重“register”变量。 示例:我在svc指令上设置了一个断点并执行

syscall<FWRITE, int>(ptr, 1, len, f)
syscall(ptr,1,len,f)
但不知何故,r0被设置为1,r1被设置为ptr。。。 我也尝试过在没有优化的情况下编译,只是寄存器的顺序有点改变,但仍然是错误的顺序。我知道我可以执行“mov r0,%[param1]”等操作,但这会阻止优化,从而导致代码速度变慢


这是GCC(4.8.2)中的一个bug,还是我忽略了什么?

这是一个问题,它相当古老。几年前我自己也遇到过它。

看起来很笨拙:-/。。。我将在C++代码中避免<代码> ASM <代码>,以供任何努力!还要注意,
register
关键字已经有一段时间不推荐使用了……相信我,如果可以的话,我会的;-)在第二个示例中,通过设置相同的缓冲区,您可能会得到您想要的结果,但仅仅通过阅读代码,您不清楚要做什么。它是ndless/TI Nspire/Nucleus RTOS。你能解释一下,如果我把参数添加为clobbers,为什么它会起作用吗?我已经试过了,但没用。不过,我会再试一次。不是每天我都会点击一个随机的SO链接并最终阅读到一个编译器错误,以支持内联汇编。。。向您致敬,先生。太好了:-(在模板中内联一个全局非模板函数的解决方法很有效。它很难看,但很有效。