问题描述
|
在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
因此,程序甚至在分配之前就跳回去。
解决方法
该代码不是有效的GNUC。首先,计算的gotos(
&&label
)是GNU C的特定功能,不是C语言的一部分,但是如果您使用的是GNU C,就可以了。但是,它们在GNU C中有效的唯一地方是goto
语句。您不能将带有内联asm的指针用作间接跳转/调用目标,因为调整堆栈框架取决于编译器,并且从内联asm和标签目标开始的堆栈框架的当前逻辑视图可能不匹配。使用显式的“ 3”语句,编译器可以对此进行修补,而使用asm甚至不能告诉它正在发生。
至于大局,如果您正在编写这样的代码,则应该重新考虑一些假设。当然,有更好的方法来完成您想要的。