WAmBerS
WAmBerS

Reputation: 314

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

I want to add two int number. If overflowing, throw an exception. When I throw an exception, the code can't be compiled. But if I don't and write other code, it's OK.

#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;
}

The error message is undefined reference to L_NO_OVERFLOW_

Upvotes: 3

Views: 791

Answers (1)

Konstantin Vladimirov
Konstantin Vladimirov

Reputation: 7009

You must use asm goto form to specify labels:

#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;
}

Idea is to tell compiler, that your inline assembler clobbers a label, and specify control flow, involving that label, directly.

UPD: Also note you must have rather new gcc to support this feature. Version > 4.5 seems to be okay. I tested on 4.8.1

Upvotes: 3

Related Questions