在gcc中启用1级优化后,我遇到了一个奇怪的问题。我所做的是稍后将标签和jmp从其他功能保存回来。
void
UMS__suspend_procr( VirtProcr *animatingPr )
{
animatingPr->nextInstrPt = &&ResumePt;
[Some Code and inline volatile asm]
ResumePt:
return;
}
我做了一些跳跃,他们都工作正常。 问题是,当我打开O1时,它不会保存正确的标签地址。相反,它做到了这一点:
804b14e: 8b 45 08 mov 0x8(%ebp),%eax
804b151: c7 40 14 4e b1 04 08 movl $0x804b14e,0x14(%eax)
804b158: 8b 55 08 mov 0x8(%ebp),%edx
所以程序在转让之前就会跳回来。
答案 0 :(得分:6)
此代码无效GNU C.首先,计算的gotos(&&label
)是特定于GNU C的功能,不是C语言的一部分,但如果您使用的是GNU C.但是,它们在GNU C中唯一有效的地方是goto
语句。您不能将带有内联asm的指针用作间接跳转/调用目标,因为调整堆栈帧取决于编译器,并且从内联asm和标签目标点的堆栈帧的当前逻辑视图可能不匹配。使用明确的goto
语句,编译器可以修补它,但是使用asm它甚至无法告诉它正在发生。
至于更大的图景,如果你正在编写这样的代码,你应该重新考虑一些你的假设。肯定有更好的方法来实现你想要的。