我知道函数参数被填充到目标字的大小,但是用什么填充?
特别是在 x86 Linux GNU 工具链的上下文中,这些函数返回什么?
int iMysteryMeat(short x)
{
return *((int *)&x);
}
unsigned uMysteryMeat(unsigned short x)
{
return *((unsigned *)&x);
}
问题是,当在汇编中手动编写函数时,是否有必要在“大”上下文中使用它们之前通过屏蔽或符号扩展来消除“小”参数(andl
, imull
).
我也很想知道这种情况下是否有任何更通用或跨平台的标准。
最佳答案
这取决于 ABI。 ABI 需要指定由调用者或被调用者(以及如何)扩展小参数的选择。不幸的是,ABI 的这一部分通常是未指定的,导致不同的编译器有不同的选择。因此,为了防止使用不同遗留编译器编译的代码之间的不兼容性,大多数现代编译器(我特别了解 i386
上的 gcc
)会谨慎行事并同时执行这两种操作。
int a(short x) {
return x;
}
int b(int x);
int c(short x) {
b(x);
}
gcc -m32 -O3 -S tmp.c -o tmp.s
_a:
pushl %ebp
movl %esp, %ebp
movswl 8(%ebp),%eax
leave
ret
_c:
pushl %ebp
movl %esp, %ebp
movswl 8(%ebp),%eax
movl %eax, 8(%ebp)
leave
jmp _b
请注意,a
不假定任何关于其参数的扩展规则,而是扩展它自己。类似地,c
确保在将其传递给 b
之前扩展其参数(通过尾调用)。
关于c - ELF 如何填充它的 `short`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12290492/