GCC 内联 ASM 跳转到带有交叉抛出异常的标签

gcc inline asm jump to a label with crossing throwing an exception

本文关键字:抛出异常 标签 ASM 内联 GCC      更新时间:2023-10-16

我想添加两个int数字。如果溢出,则引发异常。当我抛出异常时,代码无法编译。但是如果我不写其他代码,那也没关系。

#include <iostream>
#include <stdexcept>
int main()
{
    int a,b;
    std::cin >> a >> b;
    asm("movl %0, %%eax;nt"
        "addl %1, %%eaxnt"
        "jno _L_NO_OVERFLOW_nt;"
        :
        :"m"(a),"m"(b)
        :"%eax");
    throw std::overflow_error("overflow");
    //std::cout << "overflow" << std::endl;//it's OK
    asm("_L_NO_OVERFLOW_:nt"
        "movl %%eax, %0nt"
        :"=m"(a));
    std::cout << a << std::endl;
    return 0;
}

错误消息undefined reference to L_NO_OVERFLOW_

您必须使用asm goto表单来指定标签:

#include <iostream>
#include <stdexcept>
int main()
{
    int a,b;
    std::cin >> a >> b;
    asm goto ("movl %0, %%eax;nt"
              "addl %1, %%eaxnt"
              "jno %l2nt;"
              :
              :"m"(a),"m"(b)
              :"%eax"
              :L_NO_OVERFLOW);
    throw std::overflow_error("overflow");
    L_NO_OVERFLOW:
    asm("movl %%eax, %0nt"
        :"=m"(a));
    std::cout << a << std::endl;
    return 0;
}

想法是告诉编译器,你的内联汇编程序破坏了一个标签,并直接指定涉及该标签的控制流。

UPD:另请注意,您必须有相当新的 gcc 来支持此功能。版本> 4.5 似乎还可以。我在 4.8.1 上进行了测试