在 x86 上,regparm 属性会传递一个数值给编译器,这个数值会告诉编译器要用多少个寄存器来传递函数参数(EAX, EDX 或 ECX,最多 3 个寄存器),通常情况下函数是用堆栈来传递参数的。如果参数比较多,那么其余的参数仍然通过堆栈来传递。
比如我们指定 __attribute__((regparm(0))) ,则表示不用寄存器来传递参数,所有参数都通过堆栈来传递;如果我们指定 __attribute__((regparm(3))),那么就是说会用 3 个寄存器来传递参数(EAX, EDX, ECX),其余的参数通过堆栈来传递。
下面先看不用寄存器来传递参数的情况:
1 #include <stdio.h> 2 3 __attribute__((regparm(3))) int parm_to_register (int reg1, int reg2, int reg3, int stack) 4 { 5 return (reg1 + reg2 + reg3 + stack); 6 } 7 8 int main() 9 { 10 int reg1 = 1; 11 int reg2 = 2; 12 int reg3 = 3; 13 int stack = 4; 14 15 parm_to_register(reg1, reg2, reg3, stack); 16 17 return (0); 18 }
regparm 的語法是:regparm(number),regparm 屬性只在 Intel 386 平臺上有作用,用來指定最多可以有多少個("number" )參數(arguments)能以暫存器來傳遞,regparm(0) 表示參數都不能透過暫存器來傳遞,因此所有參數都會透過堆疊來傳遞。
關於regparm(3)的討論,是要求comliler從X86的暫存器(EAX,EDX,ECX)依序取值,最大就是三個。一般取值都是由所屬的stack取出。