本文介绍内核C语言程序中接触到的嵌入式汇编(内联汇编)语句。具有输入和输出参数的嵌入式汇编语句的基本格式为:asm("汇编语句"
:输出寄存器
:输入寄存器
:会被修改的寄存器);
除第一行外,后面带冒号的行若不使用就都可以省略。其实asm是内联汇编语句的关键词;"汇编语句"是你写汇编指令的地方;"输出寄存器"表示这段嵌入汇编执行完之后那些寄存器用于存放输出数据。输入寄存器表示在开始执行汇编代码时,这里指定的寄存器会存放输入值。“会被修改的寄存器”表示已对其中列出的一些寄存器的值进行改动,gcc编译器不能再依赖于它原先对这些寄存器加载的值。如果必要的话,gcc需要重新加载这些寄存器。
下面我们举例子来说明嵌入式汇编语句的使用方法。这里列出/kernel/traps。c文件中的一段代码来详细解释。
#define get_seg_byte(seg,addr)({register char __res;__asm__("push %%fs; mov %%ax,%%fs; movb %%fs:%2,%%al; pop %%fs" :"=a" (__res) :"0" (seg),"m" (*(addr)));__res;})
这段代码定义了一个嵌入式汇编宏函数。通常使用汇编语句最方便的方式就是把他们放在一个宏内。用圆括号括住的组合语句(花括号中的语句)。{}可以当做表达式使用,最后一行的变量_res是该表达式的输出值。
__asm__表示嵌入式汇编的开始。
:”=a" (_res)代表输出寄存器,意义是这段嵌入式汇编代码运行结束后将eax寄存器的值存放到_res变量中。=a称为加载代码,“=”表示这是输出寄存器,并且其中的值将被输出值代替。
:“0” (seg)表示在这段代码开始运行时将seg放到eax寄存器中,为什么是eax寄存器?就从这个0看出来的。嵌入式汇编程序规定把输出和输入寄存器统一按顺序编号,顺序是从输出寄存器开始,从左到右、从上到下,从0开始计数,因此输出寄存器的编号是0(这里只有一个输出寄存器eax)。
原文地址:http://blog.csdn.net/getnextwindow/article/details/25030939