Vault 7: Projects
This publication series is about specific projects related to the Vault 7 main publication.
MPLAB
®
XC16 C Compiler Users Guide
DS50002071C-page 210 2012-2013 Microchip Technology Inc.
EXAMPLE 16-4: CLOBBERING REGISTERS
Some instructions clobber specific hard registers. To describe this, write a third colon
after the input operands, followed by the names of the clobbered hard registers (given
as strings separated by commas). Here is an example:
asm volatile ("mul.b %0"
: /* no outputs */
: "U" (nvar)
: "w2");
In this case, the operand nvar is a character variable declared in near data space, as
specified by the U constraint. If the assembler instruction can alter the flags (condition
code) register, add cc to the list of clobbered registers. If the assembler instruction
modifies memory in an unpredictable fashion, add memory to the list of clobbered
registers. This will cause the compiler to not keep memory values cached in registers
across the assembler instruction.
EXAMPLE 16-5: USING MULTIPLE ASSEMBLER INSTRUCTIONS
You can put multiple assembler instructions together in a single asm template,
separated with newlines (written as \n). The input operands and the output operands
addresses are ensured not to use any of the clobbered registers, so you can read and
write the clobbered registers as many times as you like. Here is an example of multiple
instructions in a template; it assumes that the subroutine _foo accepts arguments in
registers W0 and W1:
asm ("mov %0,w0\nmov %1,W1\ncall _foo"
: /* no outputs */
: "g" (a), "g" (b)
: "W0", "W1");
In this example, the constraint strings g indicate a general operand.
EXAMPLE 16-6: USING & TO PREVENT INPUT REGISTER CLOBBERING
Unless an output operand has the & constraint modifier, the compiler may allocate it in
the same register as an unrelated input operand, on the assumption that the inputs are
consumed before the outputs are produced. This assumption may be false if the
assembler code actually consists of more than one instruction. In such a case, use &
for each output operand that may not overlap an input operand. For example, consider
the following function:
int
exprbad(int a, int b)
{
int c;
__asm__("add %1,%2,%0\n sl %0,%1,%0"
: "=r"(c) : "r"(a), "r"(b));
return(c);
}
The intention is to compute the value (a + b) << a. However, as written, the value
computed may or may not be this value. The correct coding informs the compiler that
the operand c is modified before the asm instruction is finished using the input
operands, as follows:
int
exprgood(int a, int b)
{
int c;
Protego_Release_01_05-Related-OEM-Documentation-MPLAB-XC16-C-Compiler.pdf