我阅读了i386和AMD64的System V ABI。他们说参数必须四舍五入为单词大小的倍数。而且我不明白为什么。
这里是情况。如果将4个char参数传递给i386体系结构上的一个函数,它将占用16个字节(每个char参数4个字节)。像为局部变量分配所有4个参数一样,仅分配4个字节不是更有效吗?
对齐不是答案。因为在两种情况下对齐16个字节的堆栈都可能需要4-12个字节的填充。
答案 0 :(得分:2)
将4个char
放在单个寄存器(或堆栈位置)中将需要创建并随后提取各个参数,这在指令方面是昂贵的。请注意,即使您在谈论堆栈,内存访问也应该非常快,因为它很可能在缓存中。
如果您真的想节省那么多空间,您仍然可以使用一个4字节的参数自己完成操作。
答案 1 :(得分:2)
...效率更高吗?
您总是必须说出要优化的地方:
如果要优化以减少堆栈使用量,将字节传递给函数确实会更有效。
但是,通常您要针对快速执行速度或较小的程序大小进行优化。
与现代编译器(将mov
用作堆栈的参数)不同,大多数1990年代编写的编译器我都知道push
堆栈的参数。如果编译器使用push
操作,则将字节放入堆栈会相当复杂-会使程序变慢和变长。
(请注意,我从未见过对参数执行pop
操作。)
答案 2 :(得分:0)
我认为原始的C语言作者更注重可移植性和可维护性,而不是压缩每个字节和每个周期。并不是说C在资源上很粗心,而是做出了适当的权衡。
将每个参数提升为堆栈粒度是合理的,而且实际上仍然可行。如果您迫切希望将其插入,则可以随时替换:
int f(int a, int b, int c, int d) { ... }
使用
struct fparm { char a,b,c,d; }; int f(struct fparm a) { ... }
现代C编译器不是那么用户友好;或更确切地说,他们唯一的朋友是名为“基准”的luser。