内联汇编简介
在Linux内核代码中有一部分是使用汇编语言编写的,尤其是与特定体系结构相关的代码和一些对性能影响很大的代码都是使用汇编语言进行编写的,那么GCC为了可以在C语言中来编写汇编代码,提供了内联汇编的功能,可以在C代码中直接内嵌汇编语言,大大方便了程序设计。
内核汇编基本语法
__asm__ [__volatiate__](
汇编语句模板
:输出部分
:输入部分
:破坏描述部分)
主要分为几个部分,gcc内核汇编前缀,汇编语句模板,输出部分,输入部分,破坏描述部分,每一个部分是用”:”分割开汇编语句模板必不可少,其他三部分可选,如果使用了后面的部分,而前面部分为空,也需要用”:”格开,相应部分内容为空。
gcc内核汇编前缀: 这个部分有一个固定前缀asm 还有可选的前缀volatiate用于控制生成的汇编代码
汇编语句模板: 这就是我们要执行的汇编指令,可能会略有一点点不同,后面会详细介绍
输出部分: 内联汇编输出的内容 asm(“movl %%cr0,%0”:”=a”(cr0)); “=a”(cr0)就是输出部分,其含义是把cr0寄存器的值赋值给cr0变量
输入部分: 内联汇编输入的内容 asm volatile(“movq %0,%%rbx”::”a”(var)); “a”(var)); “a”(var)是输入部分,其含义是把var变量的值赋值给rbx寄存器
破坏描述部分: 这个部分需要列出汇编语句模板中被修改的寄存器列表,当我们在汇编语句模板中对寄存器做了修改需要在这里列出asm volatile(“movq %0,%%rbx”::”a”(var):”bx”); “bx”是破坏描述部分,因为汇编语句模板中对rbx寄存器进行了修改。具体细节后面还会再介绍
注意: 对于输入和输出部分中的”=a”,”a”这些前缀来说不影响最终的结果,这些前缀改变了中间的过程,文章的下面会逐一介绍其含义。
一个简单的例子:
void swap()
{