3

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

4

1 回答 1

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 才能支持此功能。版本 > 4.5 似乎没问题。我在 4.8.1 上测试过

于 2013-09-18T12:24:11.000 回答