gcc inline asm 跳转到带有交叉抛出异常的标签
Posted
技术标签:
【中文标题】gcc inline asm 跳转到带有交叉抛出异常的标签【英文标题】:gcc inline asm jump to a label with crossing throwing an exception 【发布时间】:2013-09-18 03:04:50 【问题描述】:我想添加两个int
号码。如果溢出,抛出异常。
当我抛出异常时,代码无法编译。但如果我不写其他代码也没关系。
#include <iostream>
#include <stdexcept>
int main()
int a,b;
std::cin >> a >> b;
asm("movl %0, %%eax;\n\t"
"addl %1, %%eax\n\t"
"jno _L_NO_OVERFLOW_\n\t;"
:
:"m"(a),"m"(b)
:"%eax");
throw std::overflow_error("overflow");
//std::cout << "overflow" << std::endl;//it's OK
asm("_L_NO_OVERFLOW_:\n\t"
"movl %%eax, %0\n\t"
:"=m"(a));
std::cout << a << std::endl;
return 0;
错误信息是undefined reference to L_NO_OVERFLOW_
【问题讨论】:
也许你的编译器认为asm
在你的代码不可访问且未编译之后阻塞。尝试在asm
之前写volatile
。
易变死代码仍是淘汰对象
【参考方案1】:
你必须使用asm goto
表单来指定标签:
#include <iostream>
#include <stdexcept>
int main()
int a,b;
std::cin >> a >> b;
asm goto ("movl %0, %%eax;\n\t"
"addl %1, %%eax\n\t"
"jno %l2\n\t;"
:
:"m"(a),"m"(b)
:"%eax"
:L_NO_OVERFLOW);
throw std::overflow_error("overflow");
L_NO_OVERFLOW:
asm("movl %%eax, %0\n\t"
:"=m"(a));
std::cout << a << std::endl;
return 0;
想法是告诉编译器,您的内联汇编器破坏标签,并直接指定涉及该标签的控制流。
UPD:还请注意,您必须拥有相当新的 gcc 才能支持此功能。版本 > 4.5 似乎没问题。我在 4.8.1 上测试过
【讨论】:
做得很好。另外,我想知道为什么使用std::cout...
是可以的。
它不会在控制流中创建障碍,并且下一个 asm 不是死代码。以上是关于gcc inline asm 跳转到带有交叉抛出异常的标签的主要内容,如果未能解决你的问题,请参考以下文章