MPLAB C Compiler for PIC24 MCUs and dsPIC DSCs ... - Microchip
MPLAB C Compiler for PIC24 MCUs and dsPIC DSCs ... - Microchip
MPLAB C Compiler for PIC24 MCUs and dsPIC DSCs ... - Microchip
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Mixing Assembly Language <strong>and</strong> C Modules<br />
If there are no output oper<strong>and</strong>s but there are input oper<strong>and</strong>s, then there must be two<br />
consecutive colons surrounding the place where the output oper<strong>and</strong>s would go. The<br />
compiler requires that the output oper<strong>and</strong> expressions must be L-values. The input<br />
oper<strong>and</strong>s need not be L-values. The compiler cannot check whether the oper<strong>and</strong>s<br />
have data types that are reasonable <strong>for</strong> the instruction being executed. It does not<br />
parse the assembler instruction template <strong>and</strong> does not know what it means, or whether<br />
it is valid assembler input. The extended asm feature is most often used <strong>for</strong> machine<br />
instructions that the compiler itself does not know exist. If the output expression cannot<br />
be directly addressed (<strong>for</strong> example, it is a bit field), the constraint must allow a register.<br />
In that case, the compiler will use the register as the output of the asm, <strong>and</strong> then store<br />
that register into the output. If output oper<strong>and</strong>s are write-only, the compiler will assume<br />
that the values in these oper<strong>and</strong>s be<strong>for</strong>e the instruction are dead <strong>and</strong> need not be<br />
generated.<br />
EXAMPLE 9-4: CLOBBERING REGISTERS<br />
Some instructions clobber specific hard registers. To describe this, write a third colon<br />
after the input oper<strong>and</strong>s, followed by the names of the clobbered hard registers (given<br />
as strings separated by commas). Here is an example:<br />
asm volatile ("mul.b %0"<br />
: /* no outputs */<br />
: "U" (nvar)<br />
: "w2");<br />
In this case, the oper<strong>and</strong> nvar is a character variable declared in near data space, as<br />
specified by the “U” constraint. If the assembler instruction can alter the flags (condition<br />
code) register, add “cc” to the list of clobbered registers. If the assembler instruction<br />
modifies memory in an unpredictable fashion, add “memory” to the list of clobbered<br />
registers. This will cause the compiler to not keep memory values cached in registers<br />
across the assembler instruction.<br />
EXAMPLE 9-5: USING MULTIPLE ASSEMBLER INSTRUCTIONS<br />
You can put multiple assembler instructions together in a single asm template,<br />
separated with newlines (written as \n). The input oper<strong>and</strong>s <strong>and</strong> the output oper<strong>and</strong>s’<br />
addresses are ensured not to use any of the clobbered registers, so you can read <strong>and</strong><br />
write the clobbered registers as many times as you like. Here is an example of multiple<br />
instructions in a template; it assumes that the subroutine _foo accepts arguments in<br />
registers W0 <strong>and</strong> W1:<br />
asm ("mov %0,w0\nmov %1,W1\ncall _foo"<br />
: /* no outputs */<br />
: "g" (a), "g" (b)<br />
: "W0", "W1");<br />
In this example, the constraint strings “g” indicate a general oper<strong>and</strong>.<br />
EXAMPLE 9-6: USING ‘&’ TO PREVENT INPUT REGISTER CLOBBERING<br />
Unless an output oper<strong>and</strong> has the & constraint modifier, the compiler may allocate it in<br />
the same register as an unrelated input oper<strong>and</strong>, on the assumption that the inputs are<br />
consumed be<strong>for</strong>e the outputs are produced. This assumption may be false if the<br />
assembler code actually consists of more than one instruction. In such a case, use &<br />
<strong>for</strong> each output oper<strong>and</strong> that may not overlap an input oper<strong>and</strong>. For example, consider<br />
the following function:<br />
int<br />
exprbad(int a, int b)<br />
{<br />
int c;<br />
© 2008 <strong>Microchip</strong> Technology Inc. DS51284H-page 123