Pau*_*aul 5 c assembly gcc inline-assembly
我试图定义一个没有任何序言/结尾的函数,一个“到达地址”,以便它可以调用由编译器正确管理的内部函数(对调用者清除环境有用)。
我发现可以使用内联汇编程序创建全局标签,但是在同一文件中调用另一个函数时遇到问题。当我按此处列出的顺序编译代码时,我收到警告:
警告:“ handle_vmexit” [/代码/超级/内核/hyper.ko]未定义!
当我删除静态修饰符时,没有任何问题。
所以我的问题是,为什么嵌入式程序集在静态时无法与handle_vmexit链接,以及如何使其称为静态handle_vmexit。
以下是相关代码:
static void handle_vmexit(void){
...
}
__asm__(".handle_vmexit: \n\t"
"call handle_vmexit"
);
Run Code Online (Sandbox Code Playgroud)
声明C函数时static
,其他转换单元看不到C函数,因此C编译器假定它可以看到其每次使用,并根据该假设做出优化决策。如果未使用该函数,则编译器可能无法完全为其发出代码;如果仅使用一次,则可以将其内联到其唯一的调用方中,而不必单独发出其符号(GCC选项-finline-functions-called-once
),依此类推。即使您自己不使用inline
关键字(选项-finline-functions
),编译器甚至可能决定内联所有调用。*
但是,GCC无法检测到内联汇编中的用法。汇编代码对GCC完全不透明。要强制编译器无论如何都要为此函数分别发出代码,请使用__attribute__((used))
; 该属性是专门为此添加的。本手册对属性的描述如下:
used
- 附加到函数的此属性意味着,即使看起来未引用该函数,也必须为该函数发出代码。例如,仅在内联汇编中引用该功能时,此功能很有用。
当应用于C ++类模板的成员函数时,该属性还意味着,如果实例化了类本身,则实例化该函数。
*严格来说,即使函数的代码是单独发出的,编译器也可以完全不用在生成的汇编文件中声明通常的命名符号,而可以通过一些不透明的,人工生成的标识符来引用该函数,就像它一样与标签。但是我认为海湾合作委员会将永远不可能利用这种自由,特别是如果采用这里给出的解决方案。