gcc内联asm跳转到一个带有交叉抛出异常的标签

时间:2013-09-18 03:04:51

标签: c++ exception gcc assembly

我想添加两个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_

1 个答案:

答案 0 :(得分:3)

您必须使用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才能支持此功能。版本&gt; 4.5似乎没问题。我测试了4.8.1