mspgcc: A port of the GNU tools to the Texas Instruments MSP430 microcontrollers | ||
---|---|---|
<<< Previous | Next >>> |
mspgcc tries to be largely compatible with the other C language toolchains for the MSP430. Inline assembly language is one area where this is impractical. mspgcc uses the usual GCC syntax for inline assembly language, with a few extensions to deal with MSP430 specific issues. At first sight GCC's way of handling inline assembly language may seem a little more difficult to use than some of the alternatives. It is, however, generally more efficient and powerful than those alternatives.
mspgcc supports the standard GNU inline assembler feature 'asm'. In an assembler instruction using 'asm', you can specify the operands of the instruction using C expressions. This means you need not guess which registers or memory locations will contain the data you want to use.
You must specify an assembler instruction template much like what appears in an assembler language, plus an operand constraint string for each operand. For example:
asm("mov %1, %0": "=r" (result): "m" (source)); |
asm("mov %src,%res": [res] "=r" (result): [src] "m" (source)); |
Each asm statement is divided into four parts, by colons:
The assembler instructions, defined as a single string constant:
"mov %src, %res"
A list of output operands, separated by commas. Our example uses just one, and defines the identifier "res" for it:
[res] "=r" (result)
A comma separated list of input operands. Again, our example uses just one operand, and defines the identifier "src" for it:
[src] "m" (source)
The clobbered registers. This is left empty in our example, as nothing is clobbered.
asm((string asm statement) : [outputs]:[inputs]:[clobbers]); |
Each input and output operand is described by a constraint string followed by a C expression in parantheses. msp430-gcc recognises the following constraint characters:
m - memory operand.
I - integer operand.
r - register operand.
i - immediate operand (int constants in most cases).
P - constants, generated by r2 and r3.
asm("add %[bar],%[foo]" : [foo] "=r" (foo) : "[foo]" (foo), [bar] "m" (bar)); |
foo += bar; |
mov &foo, r12 /* #APP */ add &bar, r12 /* #NOAPP */ mov r12, &foo |
If there are only unused output operands, you will also need to specify 'volatile' for the 'asm' construct. If you are writing a header file that will be included in ANSI C programs, use '__asm__' instead of 'asm' and '__volatile__' instead of 'volatile'.
A percent '%' sign followed by a digit or defined tag forces GCC to substitute the relevant operand. For 4 and 8 byte operands use the A, B, C, and D modifiers to select the appropriate 16 bit chunk of the operand. For example:
#define LONGVAL 0x12345678l { long a,b; ... asm("mov %A2, %A0 \n\t" "mov %B2, %B0 \n\t" "mov %A2, %A1 \n\t" "mov %B2, %B1 \n\t" : "=r"((long)a),"=m"((long)b) : "i"((long)LONGVAL) ); ... } |
#define LONGVAL 0x12345678l { long a,b; ... asm("mov %A[longval], %A[a] \n\t" "mov %B[longval], %B[a] \n\t" "mov %A[longval], %A[b] \n\t" "mov %B[longval], %B[b] \n\t" : [a] "=r" ((long) a), [b] "=m" ((long) b) : [longval] "i"((long) LONGVAL)); ... } |
... /* #APP */ mov #llo(305419896), r12 mov #lhi(305419896), r13 mov #llo(305419896), 4(r1) ; mov #llo(305419896), &b mov #lhi(305419896), 6(r1) ; mov #lhi(305419896), &b+2 /* #NOAPP*/ mov r12, 0(r1) mov r13, 2(r1) ... |
So,
%A[tag] acts as %[tag] for a register or address constant operand, or wraps an integer value as #llo(). #llo is an assembler macro, which extracts the lower 16 bits of the value.
%B[tag] adds 1 to a register number, or 2 to an address constant, or substitutes #lhi() for an integer constant.
%C[tag] adds 2 to a register number, or 4 to an address constant, or substitutes #hlo() for an integer constant.
%D[tag] adds 3 to a register number, 6 to an address constant, or substitutes #hhi() for an integer constant.
There is also a %E modifier, which substitutes Rn from (mem:xx (reg:xx n)) as @Rn. This is a useful modifier for the first element on the stack or for pointers. !!! Do not use this unless you know exactly what are you doing !!!
<<< Previous | Home | Next >>> |
Assembler extensions | Registers, variables and labels |