Microchip Technology SW006022-2 Ficha De Dados

Página de 338
Mixing C and Assembly Code
 2012 Microchip Technology Inc.
DS52071B-page 195
        
_ _
asm
_ _
("add %1,%2,%0\n sl %0,%1,%0"
                : "=&r"(c) : "r"(a), "r"(b));
        return(c);
}
EXAMPLE 13-7: 
MATCHING OPERANDS
When the assembler instruction has a read-write operand, or an operand in which only 
some of the bits are to be changed, you must logically split its function into two separate 
operands: one input operand and one write-only output operand. The connection 
between them is expressed by constraints that say they need to be in the same location 
when the instruction executes. You can use the same C expression for both operands 
or different expressions. For example, here is the add instruction with bar as its 
read-only source operand and foo as its read-write destination:
asm ("add %2,%1,%0"
: "=r" (foo)
: "0" (foo), "r" (bar));
The constraint “0” for operand 1 says that it must occupy the same location as operand 
0. A digit in constraint is allowed only in an input operand and must refer to an output 
operand. Only a digit in the constraint can ensure that one operand will be in the same 
place as another. The mere fact that foo is the value of both operands is not enough 
to ensure that they will be in the same place in the generated assembler code. The 
following would not work:
asm ("add %2,%1,%0"
: "=r" (foo)
: "r" (foo), "r" (bar));
Various optimizations or reloading could cause operands 0 and 1 to be in different 
registers. For example, the compiler might find a copy of the value of foo in one 
register and use it for operand 1, but generate the output operand 0 in a different 
register (copying it afterward to foo’s own address).
EXAMPLE 13-8: 
NAMING OPERANDS
It is also possible to specify input and output operands using symbolic names that can 
be referenced within the assembler code template. These names are specified inside 
square brackets preceding the constraint string, and can be referenced inside the 
assembler code template using %[name] instead of a percentage sign followed by the 
operand number. Using named operands, the above example could be coded as 
follows:
asm ("add %[foo],%[bar],%[foo]"
: [foo] "=r" (foo)
: "0" (foo), [bar] "r" (bar));
EXAMPLE 13-9: 
VOLATILE ASM STATEMENTS
You can prevent an asm instruction from being deleted, moved significantly, or 
combined, by writing the keyword volatile after the asm. For example:
#define disi(n) \
asm volatile ("disi #%0" \
: /* no outputs */ \
: "i" (n))
In this case, the constraint letter “i” denotes an immediate operand, as required by the 
disi
 instruction.