我有一些简单的函数和一些内联汇编。它看起来像这样:
void hwGetCpuid( u32* p, u32 ax )
{
// printf( "hey" );
__asm __volatile
( "movl %%ebx, %%esi\n\t"
"cpuid\n\t"
"xchgl %%ebx, %%esi"
: "=a" (p[0]), "=S" (p[1]),
"=c" (p[2]), "=d" (p[3])
: "0" (ax)
);
}
我用gcc构建它。它在调试版本中正确运行。在发布版本中,它会出现故障。如果我取消注释printf,它也会在发布时正确运行。
我猜测可能会发生什么 - 这个asm的碎片在某种程度上在堆栈中是有害的。在调试中,堆栈上有额外的空间,在发布时,如果我第一次调用另一个函数,它也会填充堆栈。
但是我无法看到这个错误的代码是什么,会在发布时弄乱堆栈。或者我是不是基地,完全是其他的东西?
更新:答案是“ebx”被破坏,并且没有在clobber列表中标记。正确的代码,倒数第二行:
: "b" "0" (ax)
这里可能还有其他错误 - 但它确实在调试和释放时运行正常,但没有伪造的printf函数调用。