分类: 嵌入式
2012-12-03 11:58:31
简介:这是asm volatile ( " instructions " ) 语法解析的详细页面,介绍了和c/c++,有关的知识,和一些c/c++源码等。
The format of basic inline assembly is very much straight forward. Its basic form is内嵌汇编的一般格式如下:
asm("assembly code");
e.g.
asm("movl %ecx %eax");/*cp ecx to eax*/
__asm__("movl %eax, %ebx\n\t"
"movl $56, %esi\n\t"
"movl %ecx, $label(%edx,%ebx,$4)\n\t"
"mo%ah, (%ebx)");
In basic inline assembly, we had only instructions. In extended assembly, we can also specify the operands. It allows us to specify the input registers, output registers and a list of clobbered registers. It is not mandatory to specify the registers to use, we can leave that head ache to GCC and that probably fit into GCC’s optimization scheme better. Anyway the basic format is:
asm ( assembler template
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
The assembler template consists of assembly instructions. Each operand is described by an operand-constraint string followed by the C expression in parentheses. A colon separates the assembler template from the first output operand and another separates the last output operand from the first input, if any. Commas separate the operands within each group. The total number of operands is limited to ten or to the maximum number of operands in any instruction pattern in the machine description, whichever is greater.
If there are no output operands but there are input operands, you must place two consecutive colons surrounding the place where the output operands would go.
example:
int a=10, b;
asm ("movl %1, %%eax;
movl %%eax, %0;"
:"=r"(b) /* output */
:"r"(a) /* input */
:"%eax" /* clobbered register */
);
Here what we did is we made the value of ’b’ equal to that of ’a’ using assembly instructions. Some points of interest are:
When the execution of "asm" is complete, "b" will reflect the updated value, as it is specified as an output operand. In other words, the change made to "b" inside "asm" is supposed to be reflected outside the "asm".
If you are familiar with kernel sources or some beautiful code like that, you must have seen many functions declared asvolatileor__volatile__which follows anasmor__asm__. I mentioned earlier about the keywordsasmand__asm__. So what is thisvolatile?
If our assembly statement must execute where we put it, (i.e. must not be moved out of a loop as an optimization), put the keywordvolatileafter asm and before the ()’s. So to keep it from moving, deleting and all, we declare it as
asm volatile ( ... : ... : ... : ...);
Use__volatile__when we have to be verymuch careful.
If our assembly is just for doing some calculations and doesn’t have any side effects, it’s better not to use the keywordvolatile. Avoiding it helps gcc in optimizing the code and making it more beautiful.
The NEON register bank consists of 32 64-bit registers. If both Advanced SIMD and VFPv3 are implemented, they share this register bank. In this case, VFPv3 is implemented in the VFPv3-D32 form that supports 32 double-precision floating-point registers. This integration simplifies implementing context switching support, because the same routines that save and restore VFP context also save and restore NEON context
The NEON unit can view the same register bank as: • sixteen 128-bit quadword registers, Q0-Q15 • thirty-two 64-bit doubleword registers, D0-D31.