Linux系统调用中的DOARGS_##args;和UNDOARGS_##args;语句是什么意思?

Linux系统调用中的DOARGS_##args;和UNDOARGS_##args;语句是什么意思?

args 本身是 DO_CALL 宏的参数,表示系统调用的参数个数,所以 DOARGS_##args 的展开结果不是 DOARGS_args 而是 DOARGS_ 和 args 的值连接起来,比如 args=3 的话就是 DOARGS_3

目的就是做一些保存和恢复的工作,比如 linux/eabi 是用 r7 来传递系统调用号,但是 r7 本身是 callee-saved 的,所以 ldr r7, =__NR_syscall 之前要将它保存到栈上。另外 linux 是用 r0-r7 来传递参数,但是 arm eabi 是用 r0-r3 传递前 4 个参数其余的用栈,所以在系统调用有多于 4 个参数的时候就要把 r4-r6 压栈然后从栈上加载真正的参数到这几个寄存器里。总结起来就是 0-4 个参数压 r7,>4 个参数压 r7 和 r4-r6 里面用到的寄存器然后从栈里面 ldmia 出参数

这些保存和恢复工作都被定义成了宏 DOARGS_n 和 UNDOARGS_n,比如 DOARGS_1 就是系统调用有一个参数时该做的保存工作(当然,0-4 个参数时候处理都是一样的,只需要将 r7 压栈)

那在 DO_CALL 里面就可以用参数个数 args 来选择相应的 DO/UNDOARGS_n 了,比如 read 有 3 个参数