在gcc中打开优化后的标签移动

0 c optimization x86 label gcc

在gcc中启用1级优化后,我遇到了一个奇怪的问题.我所做的是稍后将标签和jmp从其他功能保存回来.

void
UMS__suspend_procr( VirtProcr *animatingPr )
{ 
   animatingPr->nextInstrPt = &&ResumePt;


   [Some Code and inline volatile asm]

   ResumePt:
   return;
Run Code Online (Sandbox Code Playgroud)

}

我做了一些跳跃,他们都工作正常.问题是,当我打开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
Run Code Online (Sandbox Code Playgroud)

所以程序甚至在分配之前就会跳回来.

R..*_*R.. 6

这段代码是无效的GNU C.首先,计算的gotos(&&label)是特定于GNU C的特性,不是C语言的一部分,但是如果你使用的是GNU C就可以.但是,它们是唯一的地方在GNU C中有效的是goto声明.您不能将带有内联asm的指针用作间接跳转/调用目标,因为调整堆栈帧取决于编译器,并且从内联asm和标签目标点的堆栈帧的当前逻辑视图可能不匹配.使用显式goto语句,编译器可以修补它,但是使用asm它甚至无法告诉它正在发生.

至于更大的图景,如果你正在编写这样的代码,你应该重新考虑一些你的假设.肯定有更好的方法来实现你想要的.

  • 堆栈不好.编译器可以随时调整它*但是它需要*并且它在你的控制范围之外.你根本不被允许做任何你想做的事情.它如果"有效",那就是纯粹的运气,它可以并且将会打破. (2认同)