我发现很多例子都是使用asm来运行Hello World系统调用,但是没有人讨论过调用带有返回值的系统调用。我的代码是
int my_syscall(int sn)
{
int output_variable = 0;
int input_variable = sn;
__asm__ volatile(
"mov r7,%1\n\t"
"svc 0\n\t"
"mov %0,r0\n\t"
:"=r"(output_variable)
:"r"(input_variable)
);
return output_variable;
}
在ARM linux上运行它(BeagleBone Black)会给我一个分段错误。
答案 0 :(得分:0)
修复:解决方法是使用" -fomit-frame-pointer"使用arm-linux-gnueabihf-gcc编译时的指令(也可能用于其他版本)。
$arm-linux-gnueabihf-gcc {YOUR FILE NAME}.c -fomit-frame-pointer -o {YOUR OUTPUT FILE NAME}
谢谢大家的所有评论。因此,对于记录,问题中的上述代码逻辑是有效的。据我所知,问题是编译器出于某种原因使用r7作为帧指针。您可以继续添加参数作为输入,并使用内联汇编创建更通用的系统调用实现。考虑一下人们在评论中所说的更好的实现。
伪代码
returntype my_syscall(int syscallnumber,type arg1,type arg2,..)
{
int output_variable = 0;
__asm__ volatile
(
"mov r7,[sysnum]\n\t"
"mov r0,[var1]\n\t"
"mov r1,[var2]\n\t"
//continue similarly for more input arguments etc
"svc 0\n\t"
"mov %0,r0\n\t" //Return value of syscall will be available in r0 for ARM EABI
:"=r"(output_variable)
:[sysnum]"r"(syscallnumber),[var1]"r"(arg1),[var2]"r"(arg2) //and so on for other arguments
:"memory" //clobber others based on usage
);
return output_variable;
}
背景故事(对于任何感兴趣的人):当我实现一个简单的" Hello World"时,相同的代码(问题中存在的代码)略有变化。字符串写入(更改包括不同的系统调用号和参数)。但是,当我调用返回所需值的自定义系统调用时,它不起作用(或者,您可以设计系统调用以使用参数而不是返回指令返回值以避免整个问题。我没有这样做因为那时我将不得不重新编译整个内核,但我离题了。我用内置的syscall()函数测试了我的系统调用,它运行得很好。但是 MY syscall()函数的实现无法调用 MY 自定义系统调用。 我尝试了注册变量,我尝试了不同的指令和破坏了r0,内存等(在我问这里之前的问题)但似乎什么都没有用。然后我尝试了破坏r7,编译器说你不能这样做。所以当我发现r7寄存器被用于其他东西时。当我用Google搜索错误时,我找到了上面的fix。 具有讽刺意味的是,在修复之后它没有破坏r7或其他任何东西。洛尔。