i am new to assembly programming,can anybody help me out to solve this problem -

i have a assembly code which does the atomic increment

Atomic_Add (volatile unsigned int *addr, int additive)
{
    register unsigned int previous;

    __asm__ volatile (
        "pushf;"
        "cli;"
        "movl   (%2), %0;"      /* previous = *addr; */
        "add    %0, %1;"        /* *addr = previous + additive; */
        "movl   %1, (%2);"
        "popf"
    : "=&r"(previous)
        : "r"(additive), "r"(addr) : "cc");
    return previous;
}

here if addr is allocated on the stack(local variable) this function works fine and increment the addr variable correctly by additive, but if i addr is allocated on heap or is from gss, addr is not getting incremented correctly. and one more thing, if i merge the last two instruction the code works fine for all the scenarios.

Atomic_Add (volatile unsigned int *addr, int additive)
{
    register unsigned int previous;

    __asm__ volatile (
        "pushf;"
        "cli;"
        "movl   (%2), %0;"      /* previous = *addr; */
        "add    %1, (%2);"        /* *addr = previous + additive; */
        "popf"
    : "=&r"(previous)
        : "r"(additive), "r"(addr) : "cc");
    return previous;
}

So is the "not working properly" related to the "add" part of the problem or the "lock" part of the problem?

cli isn't going to do anything useful at all if you have multiple cores. AFAIK, it's a "per core" thing, so disabling it on one doesn't stop the other from messing with the variable.

The use case you quote of locals good, globals bad makes it seem like a cache coherency problem. Or it could be down to out-of-order execution of instructions meaning the popf happens beforre the memory write. IIRC, the instruction to stop this is 'sync'

This article has been dead for over six months. Start a new discussion instead.