Chinaunix首页 | 论坛 | 博客
  • 博客访问: 17618
  • 博文数量: 8
  • 博客积分: 145
  • 博客等级: 入伍新兵
  • 技术积分: 80
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-27 20:11
文章分类
文章存档

2012年(6)

2011年(2)

我的朋友

分类: 嵌入式

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:

  • "b" is the output operand, referred to by %0 and "a" is the input operand, referred to by %1.
  • "r" is a constraint on the operands. We’ll see constraints in detail later. For the time being, "r" says to GCC to use any register for storing the operands. output operand constraint should have a constraint modifier "=". And this modifier says that it is the output operand and is write-only.
  • There are two %’s prefixed to the register name. This helps GCC to distinguish between the operands and registers. operands have a single % as prefix.
  • The clobbered register %eax after the third colon tells GCC that the value of %eax is to be modified inside "asm", so GCC won’t use this register to store any other value.

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.

阅读(6942) | 评论(0) | 转发(0) |
0

上一篇:vim使用

下一篇:linux下adb工具的安装

给主人留下些什么吧!~~