您的位置:首页 > 其它

GCC内联汇编

2009-11-24 23:59 337 查看
gcc内联汇编
在gcc编译器中允许出现内联汇编代码。运用一种特定的形式告诉编译器这段代码不需要编译。
内联汇编的格式如下:

-----------------------------------------------------------------------
1 asm (assembler instruction(s)
2 : output operands (optional)
3 : input operands (optional)
4 : clobbered registers (optional)
5 );
-----------------------------------------------------------------------
例如,它的基本形式为:
asm ("movl %eax, %ebx");
也可以写为
asm ("movl %eax, %ebx" : : :);
具体解释:
1.output operands:输出操作数
输出操作数是在括号中的一个C表达式列表,前面加上“constraint”。对于输出表达式,我们通常在前面有个"="作为限制符,表明它是只读的。
"&"表明它是"early clobber" 操作,。每个操作数用逗号隔开。

2输入操作数
除了只读属性外,它与输出操作数有相同语法

3参数编号
每个参数都有一从0开始的位置编码。
例如,这里有一个输入参数和两个输出参数,那么%0表示这个输出参数,%1,%2分别表示两个输出参数。

4 Constraint

Simple and Machine Constraints for x86
Constraint Function
a eax register.
b ebx register.
c ecx register.
d edx register.
S esi register.
D edi register.
I Constant value (0…31).
q Dynamically allocates a register from eax, ebx, ecx, edx.
r Same as q + esi, edi.
m Memory location.
A Same as a + b. eax and ebx are allocated together to form a 64-bit register.

5关键字asm
实际应用中,我们通常使用__asm_,因为asm可能会与其他的结构体同名而发生编译错误。

6.关键字 __volatile_
标识符__volatile_在汇编代码非常重要。它告诉编译器不要对这个内敛汇编进行优化。
通常,在底层代码中,编译器认为我们写的代码总是有冗余和浪费,从而对其进行优化从而提高效率。
对于应用级编程来说,这是相当使用的,但是对于底层来说,这反而达不到预期效果。

例如,我们要写一个由变量reg表示的内存映射寄存器,在初始化中我们首先要检测reg,编译器则会简单的认为这个连续
的读同一个内地位置,就会消除这个明显的冗余。使用__volatile_,编译器就知道不去优化这个读操作。

现在我们已经对gcc内联汇编有了基本的认识,我们可以来看一些实际的内敛汇编代码:

例1:
-----------------------------------------------------------------------
6 int foo(void)
7 {
8 int ee = 0x4000, ce = 0x8000, reg;
9 __asm__ __volatile__("movl %1, %%eax";
10 "movl %2, %%ebx";
11 "call setbits" ;
12 "movl %%eax, %0"
13 : "=r" (reg) // reg [param %0] is output
14 : "r" (ce), "r"(ee) // ce [param %1], ee [param %2] are inputs
15 : "%eax" , "%ebx" // %eax and % ebx got clobbered
16 )
17 printf("reg=%x",reg);
18 }
-----------------------------------------------------------------------
其中reg,ce,ee作为本地变量传递给内联汇编。

9:内联汇编例程的开始,将ce移到eax中
10: 将dd移到ebx中
11:调用一个函数
12:返回eax中的值,并赋值给reg
13:输出参数列表,这里只有一参数reg
14:输入参数列表,ce和ee
15:破坏描述部分,“%eax,%ebx” 说明在内联汇编代码中将要改变eax和ebx中的内容,GCC不要用他存储其他值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: