c - ELF 如何填充它的 `short`?

标签 c assembly x86 inline-assembly

我知道函数参数被填充到目标字的大小,但是用什么填充?

特别是在 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/

相关文章:

c - 如何在 ARM 汇编程序中使用 C 定义

memory-management - 动态堆分配困惑

c++ - CRichEditCtrl 加载 Unicode 文本不正确

c、malloc 和 realloc 结构体数组

指向匿名字符数组的字符指针

windows - 调用ExitProcess时应该如何准备堆栈?

assembly - x86 cmpl 和 jne

c++ - GCC下的_rotl64相当于什么

linux - 如何逐步调试没有符号或部分的程序集二进制文件?

c - C将值存储到数组中而不覆盖的字符串