Chinaunix首页 | 论坛 | 博客
  • 博客访问: 134127
  • 博文数量: 37
  • 博客积分: 2671
  • 博客等级: 少校
  • 技术积分: 335
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-11 13:18
文章分类

全部博文(37)

文章存档

2011年(16)

2010年(21)

我的朋友

分类: C/C++

2011-02-27 23:41:41

The format of basic inline assembly is very much straight forward. Its basic form is

asm("assembly code");

Example.

asm("movl %ecx %eax"); /* moves the contents of ecx to eax */


__asm__("movl %eax, %ebx\n\t"
          "movl $56, %esi\n\t"
          "movl %ecx, $label(%edx,%ebx,$4)\n\t"
          "movb %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 as volatile or __volatile__ which follows an asm or __asm__. I mentioned earlier about the keywords asm and __asm__. So what is this volatile?

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 keyword volatile after 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 keyword volatile. Avoiding it helps gcc in optimizing the code and making it more beautiful.

 

 

 

 

阅读(3412) | 评论(1) | 转发(0) |
0

上一篇:how to use Gconf

下一篇:ar命令详解

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

chinaunix网友2011-03-05 13:11:38

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com