尽管基思的回答符合我的问题的精神,但根据亚历克斯的要求,我想我会自己尝试一下。
有趣的是,在这种情况下,对我的例子更直接的回答是“垃圾”。
#include <stdio.h>
int iMysteryMeat(short x)
{
return *((int *)&x);
}
unsigned uMysteryMeat(unsigned short x)
{
return *((unsigned *)&x);
}
int main()
{
printf("iMeat: 0x%08x\n", iMysteryMeat(-23));
printf("uMeat: 0x%08x\n", uMysteryMeat(-23));
return 0;
}
gcc -m32 -S meat.c
iMysteryMeat:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
movw %ax, -4(%ebp)
leal -4(%ebp), %eax
movl (%eax), %eax
leave
ret
uMysteryMeat:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
movw %ax, -4(%ebp)
leal -4(%ebp), %eax
movl (%eax), %eax
leave
ret
./a.out
iMeat: 0x0804ffe9
uMeat: 0x0043ffe9
如您所见,不仅通常的符号扩展协议被覆盖(即与 Keith 的 比较a()
),它实际上将 x 移动到未初始化的堆栈空间中movw
,无论main()
给出什么,都会呈现返回值的上半部分垃圾。
所以,再次,正如 ouah 所说,永远不要在 C 中这样做,在汇编中(或者一般来说,真的),总是对你的输入进行消毒。