ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

linux kernel(内核)代码理解 几个记录(属性、内联汇编、__builtin()、 likely()等)

2021-07-19 02:01:33  阅读:287  来源: 互联网

标签:__ kernel struct ... builtin eax likely 寄存器


1. GNU汇编器采用了AT&T语法,和流行的Intel/Microsoft语法形势存在差异(主要是元寄存器和目标寄存器的排列不同)。 AT&T汇编语法总结:

    a)寄存器通过在名称前加%引用,比如为使用eax寄存器,汇编代码中讲使用 %eax(说明:在C源代码中需使用2个%表示,即%%eax).

    b)  源寄存器总是在目标寄存器之前指定。比如 mov a, b表示将寄存器a的值复制到寄存器b, movl $5, %edx;将5存入edx。//对应Intel语法为 mov b, a,比如mov eax, 0x0;

    c)操作数的长度有汇编语句的后缀指定,b代表byte,l--long,w--word, 为在IA-32系统上讲一个长整数从eax寄存器移动到ebx寄存器,需要: movl %eax,%ebx。

    d)指针反引用需要将寄存器包含在括号中。例如 movl (%eax), %ebx 表示将寄存器eax的值指定的内存地震中的长整数值复制到寄存器ebx。//对应intel语法:  mov DWORD PTR [ebp-4], 0x3。将3存入ebp-4对应值的地址中去

    e)offset(register)指定寄存器值与一个偏移量联用,将偏移量加到寄存器的实际值上。例如 8(%eax)指定将eax+8作为一个操作数。

2、内联汇编

     GCC借助专门的语句,将简短的汇编语言代码片段插入到C代码中,编译器来承担联合代码生成的工作。

     asm语句用于指定汇编代码和所用的寄存器(也可以使用__asm__关键字),语法如下:

     asm("Assembler code";

                  : Output operand specification

                  : Input operand specification

                  : Modified registers. 即临时的工作寄存器

      );

     如下代码实现b=a的功能(不一定性能最优,仅做举例说明用):

      int move() {

         int a = 5;

         int b;

         asm  ("movl %1, %%eax;   /*%1 表示输入寄存器*/

                    movl %%eax, %0;"   /*%0 表示输入寄存器*/

                    : "=r" (b)  /*输出寄存器, =表示只写即丢弃前一个值直接替换为操作的输出值;+表示操作数是读写的; r表示寄存器,m表示内存地址*/

                    : "r" (a) /*输入寄存器*/

                    : "%eax"); /*临时工作寄存器*/

           printf("b: %u\n", b);

       }

      上述内联汇编代码使用了一个输入寄存器,一个输出寄存器和一个临时寄存器。%0, %1表示由编译器指定寄存器,代码不关心具体名字。

3、__builtin函数

     __builtin函数向编译器提供了其他选项,可以执行C语言常规能力范围之外的操作,又不比借助于内联汇编。常用的比如:

     __builtin_expect(long exp, long c)帮助编译器优化分支预测。exp指定一个将计算的表达式的结果值,而c返回预期结果(0或1)。

     比如如下代码 预期条件表达式在大多数情况下值为1,那么可用__builtin_expect优化性能:

     if( __builtin_expect(expression, 1)) {

         ... /*编译器通过预先计算该分支,来影响处理器的分支预测*/

     } else {

     ...

    }

    内核定义了一下两个宏,来标识代码中很可能和不太可能的分支:

    <complier.h>

    #define likely(x)      __builtin_expect( !!(x), 1)

    #define unlikely(x)  __builtin_expect( !!(x), 0)

    这里使用双重否定!!符号是为了:

    a)使得宏可以用于隐式转换为真值的指针;

    b)大于0的真值标准化为1,这是__builtin_expect所预期的值。

    代码示例(mm/slab.c)

    if (likely(ac-avail < ac->limit)) { ...} else { }  /*x 可以为运算表达式*/

 

4. container_or()

    如果结构A包含一个子结构B,则A称之为B的一个容器,例如:

    struct A {

       ...

         struct B {

         }element;

       ...

    } container;

   查找元素的容器对象实例(kernel.h):

   #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*) 0)->MEMBER)  /*将空指针0转换为一个TYPE*的指针,成员地址即偏移量*/

   struct test {                                                         |   struct test {

     int a,b;                                                              |     struct list_head *f_list;

     struct list_head *f_list;                                      |      int a,b,c;

     int c;                                                                 |   } b;

    } a;                                                                       |

   offsetof(struct test, f_list) ==>值为8                  |   offsetof(struct test, f_list) ==>值为0

   

   /* container_of  从结构的成员来获得包含成员的结构实例

    * @ptr:            指向成员数据的指针

    * @type:         所嵌入到的容器结构的类型

    * @member:  成员在结构内的名称

    */

    #define container_of(ptr, type, member)   ( {               \

                 const typeof( ((type*) 0)->member) *__mptr = (ptr);  \

                 (type*) ( (char*) __mptr - offsetof(type, member) ); } )      /*为确保指针计算是按字节执行的,先将_mptr转为为char* 指针,计算完成后的赋值操作中再转回原来的数据类型*/

    比如 container_of(&a.f_list, struct test, f_list).  

 

5、LXR(本部分还未验证)

     LXR是一个交叉引用工具,可用于分析内核源代码并生成一个HTML形式的超文本表示,供浏览器查看。

     为在本地使用LXR,需要一个浏览器和一个WEB服务器,最好是apache,为随机字符串搜索,还需要glimpse搜索引擎。

     git库: git://lxr.linux.no/git/lxrng.git.     

     DDD data display debugger, 图形化gdb

     用户模式linux, User-Mode-Linux), 内核在linux系统上以一个用户空间进程的形式运行,方便调试。

 

    

  • 添加到短语集  
    • 没有此单词集:罗马尼亚语 → ...  
    • 创建新的单词集...
  • 拷贝
  • 添加到短语集  
    • 没有此单词集:英语 → ...  
    • 创建新的单词集...
  • 拷贝

标签:__,kernel,struct,...,builtin,eax,likely,寄存器
来源: https://www.cnblogs.com/ypingan/p/15028542.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有