GCC内联汇编

  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不要用他存储其他值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值