Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens in the assembly output when we add "cc" to clobber list

I read that if we specify "cc" in clobber list it indicates that an assembler code modifies flags register

Wrote a sample program to check the difference in between adding "cc" and not adding. Comparing the assembly there is no change when we add "cc".

#include <stdio.h>

int main(void)
{
        unsigned long sum;

        asm("incq %0" 
        : "=r"(sum)//output operand
        : "r" (sum) //input operand
    );
        printf("sum= %lu\n", sum);
        return 0;
}

When should we use "cc", and what is the effect of it in the assembly output

like image 649
md.jamal Avatar asked Mar 03 '23 23:03

md.jamal


1 Answers

For x86, absolutely nothing. For x86 and x86-64, a cc clobber is implicit in every asm() statement. This design decision makes some sense because most x86 instructions wrote FLAGS. And because it's easy to miss and could be hard to catch with testing. (Although there's no shortage of things that are easy to get wrong with GNU C inline asm. There's usually no need to use it.)

(It does make it impossible to tell the compiler when your asm statement doesn't modify flags, but the cost of that is probably low, usually just one more instruction to redo a compare or something, or to save a variable so it can be compared later.)

If you want to be pedantic, you can use a "cc" clobber in every asm statement that modifies FLAGS.


For non-x86, you must use a cc clobber in every asm statement that modifies flags / condition codes (on ISAs that have them). e.g. ARM. On ARM, setting flags is optional; instructions with an S suffix set flags. So adds r0, r1, r2 sets flags according to r0 = r1+r2, but add r0, r1, r2 leaves flags untouched.

If you left out a "cc" clobber (on non-x86), the compiler might emit asm that set flags before an asm statement and read them afterwards, as part of implementing some other non-asm statement. So it could be essentially the same as destroying a register: nonsensical behaviour that depends on the details of what the compiler was using the register or the flags for, and which varies with optimization level and/or compiler version.

This is why testing isn't sufficient to prove inline asm is safe. With one compiler version, you could easily get lucky and have the compiler generate code that happened not to keep anything in the status register / condition codes across an asm statement, but a different compiler version or different surrounding code in a function where this inlines could be vulnerable to a buggy asm statement.

like image 125
Peter Cordes Avatar answered Mar 05 '23 17:03

Peter Cordes