ARM系统调用作为c++模板
ARM syscall as c++ template
我需要在我的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;
}
现在我可以使用
调用mallocvoid *ptr = syscall<SYS_MALLOC, void*>(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;
}
不起作用,"swi"指令寄存器的内容是任意的。不知何故,GCC不再尊重"寄存器"变量了。示例:我在svc指令处设置了一个断点并执行
syscall<FWRITE, int>(ptr, 1, len, f)
但不知何故,r0被设置为1,r1被设置为ptr…我也尝试编译没有优化,只是寄存器的顺序改变了一点,但它仍然是错误的顺序。我知道我可以这样做"mov r0, %[param1]"等,但这会阻止优化,从而导致较慢的代码。
是GCC(4.8.2)中的一个bug还是我忽略了什么?
这是bug 33661,相当老了。我几年前也遇到过。
在2021年,也就是这个问题和答案最初编写的6年后,它被修复了。
相关文章:
- .cpp和.h文件中的模板专用化声明
- C++模板来检查友元函数的存在
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 如何在c++中为模板函数实例创建快捷方式
- 使用C++中的模板和运算符重载执行矩阵运算
- 有人能分解一下这个c++模板的语法吗
- 如何在c++17中制作一个模板包装器/装饰器
- 模板化建造师专业化
- 调用专用模板时出错"no matching function for call to [...]"
- 模板元程序查找相似的连续类型名称
- 如何在C++20中创建模板别名的推导指南
- 没有名称的C++模板参数
- 具有重复类型的C++可变模板
- 如何将enable-if与模板参数和参数包一起使用
- 没有用于初始化C++中的变量模板的匹配构造函数