考虑以下小功能:
void foo(int* iptr) {
iptr[10] = 1;
__asm__ volatile ("nop"::"r"(iptr):);
iptr[10] = 2;
}
Run Code Online (Sandbox Code Playgroud)
使用gcc,它将编译为:
foo:
nop
mov DWORD PTR [rdi+40], 2
ret
Run Code Online (Sandbox Code Playgroud)
请特别注意,即在第一次写iptr,iptr[10] = 1根本不会发生:内联汇编nop是在函数的第一件事,只有最后写2(会出现ASM呼叫后)。显然,编译器决定只需要提供其iptr 自身值的最新版本,而不需要提供其指向的内存。
我可以告诉编译器,内存必须是最新的memory,就像这样:
void foo(int* iptr) {
iptr[10] = 1;
__asm__ volatile ("nop"::"r"(iptr):"memory");
iptr[10] = 2;
}
Run Code Online (Sandbox Code Playgroud)
结果为预期的代码:
foo:
mov DWORD PTR [rdi+40], 1
nop
mov DWORD PTR [rdi+40], 2
ret
Run Code Online (Sandbox Code Playgroud)
但是,这太强了,因为它告诉编译器必须写入所有内存。例如,在以下功能中:
void foo2(int* iptr, long* …Run Code Online (Sandbox Code Playgroud) 我是一个内核新手,面临着一个奇怪的问题.我编写了一个概念验证计算器系统调用,虽然它适用于大多数计算,但当SUBTRACTION结果介于-1到-256之间时它返回-1.如果有人可以对可能发生的事情有所了解,那就会很感激.下面是系统调用代码.
SYSCALL_DEFINE3(calc, int, a, int, b , char, op) {
int res_int;
switch(op) {
case '+': res_int = a + b;
break;
case '-': res_int = a - b;
break;
case '*': res_int = a * b;
break;
case '/': res_int = (a*1000) / b;
break;
}
printk(KERN_INFO "KERNEL CALC RESULT : %d %c %d = %ld",a, op, b, res_int);
return res_int;
}
Run Code Online (Sandbox Code Playgroud)
编辑:内核版本:Android Linux内核3.10.xxx.平台:Nexus7 ARM EABI.我不明白的是它失败的原因.errno完全没用,因为它将-res_int设置为errno.另外,我不明白为什么只有当res_int为{-1,-256}时才会失败.
a = 1200,b = 1300 op =' - '=> res_int = -100是printk打印-100的示例,但在我的用户空间应用程序中,我收到-1.
看起来当res_int为{-1,-256}时,errno被设置为-res_int. …
据我所知,ARM 的 Linux ABI 声明系统调用返回值是通过传递的r0,如果它是负数,它应该被线程化为 errno 值否定。即系统调用结束了一些错误。AOSP以某种奇特的方式执行此检查:
ENTRY(syscall)
mov ip, sp
stmfd sp!, {r4, r5, r6, r7}
.cfi_def_cfa_offset 16
.cfi_rel_offset r4, 0
.cfi_rel_offset r5, 4
.cfi_rel_offset r6, 8
.cfi_rel_offset r7, 12
mov r7, r0
mov r0, r1
mov r1, r2
mov r2, r3
ldmfd ip, {r3, r4, r5, r6}
swi #0
ldmfd sp!, {r4, r5, r6, r7}
.cfi_def_cfa_offset 0
cmn r0, #(MAX_ERRNO + 1) /* Set C flag if r0 is between -4095 and -1, set …Run Code Online (Sandbox Code Playgroud) assembly ×2
system-calls ×2
arm ×1
c ×1
clang ×1
gcc ×1
kernel ×1
libc ×1
linux ×1
linux-kernel ×1