GCC内联函数

来源:互联网 发布:科目三路考软件 编辑:程序博客网 时间:2024/06/17 06:36

(1)GCC基本内联函数
基本格式 asm(“statement”); 例如:asm(“nop”);asm(“cli”);
其中“asm”“asm”含义一样。如果有多行汇编,则每一行需加上“\n\t”。其中的“\n”是换行符,“\t”是tab符。目的是编译时,能保证正常换行并留有一定的空格。
例如:asm(“push1 %eax\n\t”
“movl $0,%eax\n\t”
“popl %eax”
);
(2)GCC扩展内联汇编
例如:

#define read_cr0()({\    unsigned in _dummy;        _asm_(\        "movl %%cr0,%0\n\t"\        :"=r"(_dumy));\        _dumy;\    })

GCC扩展内联汇编的基本格式
asm [volatile](Assembler Template
:Output Operands
[:Input Operands
[:Clobbers]])
其中,asm表示汇编代码的开始,其后可以跟volatile(可选)。含义是避免“asm”指令被删除、移动或组合,在执行代码时,如果不希望汇编语句被gcc优化而改变位置,则需要加。“”为汇编指令部分。数字前的%表示使用寄存器的样板操作数。因此

注:在内联汇编语句中使用寄存器eax时,寄存器名前应该加两个’%’,即%%eax。内联汇编中使用%0、%1等来标识变量,任何只带一个’%’的标识符都看成是操作数,而不是寄存器。
样板操作数
操作数0——为一字符串,称为指令名。该字符串可以为空,当非空时,它要么为gcc 规定的标准指令名,要么为开发者任意给定的名字。非标准名和空名的指令样板只在gcc 编译的汇编代码生成过程中起作用。标准指令名的样板还在RTL 生成中起作用。
操作数1——为一不完全的rtx 表达式或向量,称为RTL 模板。它表示该指令样板的RTL 指令体。RTL 模板只规定了RTL 指令体中的各种操作以及操作数的位置和操作数必须满足的条件和限制,并未指明具体的操作数。
操作数2——为一字符串,称为条件。这个字符串或者为空,或者为一C 条件表达式。当非空时,它指出此样板有效的条件。
操作数3——为一字符串,称为输出模板。输出模板用来确定与此样板相匹配的RTL 指令的汇编输出形式,它有三种形式:单个汇编模板,多个汇编模板以及C 代码。前二种形式直接就是目标机的汇编指令,汇编模板中用特殊字符‘%’后随数字或其它字符指明各操作数的位置和输出格式。第三种C代码形式适用于不能直接静态给出汇编模板的情形,这段汇编代码将被编译程序吸收并用动态产生汇编模板。
操作数4——它为一任选的rtx 向量,称为指令属性。当此操作数出现时,它给出与这一样板相匹配的指令的属性
输出部分(Output Operands list):用以规定输出变量(目标操作数)如何与寄存器结合的约束(constraint),输出部分可以有多个约束,互相以逗号分开。每个约束以“=”开头,跟着一个字母表示操作数的类型,然后是关于变量集的约束。
“=r”表示相应的目标操作数(指的是%0)可以用任何一个通用寄存器,并且变量_dummy存放在这个寄存器中,下面是约束字母及含义
这里写图片描述
输入部分(input operand list):输入部分与输出部分相似,但没有“=”。如果输入部分一个操作数所要求使用的寄存器,与前面输出部分某个约束所要求的是同一个寄存器,那就把对应操作数的编号(如“1”,“2”等)放在约束条件中。在后面的例子中,可看到这种情况。修改部分(clobber list,也称 乱码列表):这部分常常以“memory”为约束条件,以表示操作完成后内存中的内容已有改变,如果原来某个寄存器的内容来自内存,那么现在内存中这个单元的内容已经改变。乱码列表通知编译器,有些寄存器或内存因内联汇编块造成乱码,可隐式地破坏了条件寄存器的某些位(字段)。

原创粉丝点击