加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

2.2.1内嵌汇编

发布时间:2020-12-14 00:01:41 所属栏目:Linux 来源:网络整理
导读:内容来源于《庖丁解牛Linux内核分析》-孟宁等 ??|-- 第2章操作系统是如何工作的 ????|--2.2借助Linux内核部分源代码模拟存储程序计算机工作模型及时钟中断 ??????|--2.2.1内嵌汇编 有修改,大部分一样 C语言内嵌汇编语法如下: __asm__ __volatile__ ( 汇编

内容来源于《庖丁解牛Linux内核分析》-孟宁等
??|-- 第2章操作系统是如何工作的
????|--2.2借助Linux内核部分源代码模拟存储程序计算机工作模型及时钟中断
??????|--2.2.1内嵌汇编

有修改,大部分一样

C语言内嵌汇编语法如下:

__asm__ __volatile__ (
    汇编代码
    输出部分
    输入部分
    破坏性描述部分(可以省略)
);

下面通过一个简单的例子来熟悉内嵌汇编的语法规则

#include <stdio.h>

int main()
{
    /* val1+val2=val3 */
    unsigned int val1 = 1;
    unsigned int val2 = 2;
    unsigned int val3 = 0;
    printf("val1:%d,val2:%d,val3:%dn",val1,val2,val3);
    asm volatile(
        "movl $0,%%eaxnt"      /* clear %eax to 0 */
        "addl %1,%%eaxnt"      /* %eax += val1 */ 
        "addl %2,%%eaxnt"      /* %eax += val2 */ 
        "movl %%eax,%0nt"      /* val2 = %eax */
        : "=m" (val3)            /* output =m mean only write output memory variable */
        : "c" (val1),"d" (val2) /* input c or d mean %ecx/%edx */ 
    );
    printf("val1:%d+val2:%d=val3:%dn",val3);

    return 0;
}

这个例子是用汇编代码是想val3=val1+val2的功能(能在windows10,mingw-gcc上编译运行正确),具体解释如下

  1. __asm__是GCC关键字asm的宏定义,是内嵌汇编的关键字,表示这是一条内嵌汇编语句。__asm__asm可以互相替换使用:#define __asm__ asm
  2. __volatile__是GCC关键字volatile的宏定义,告诉编译器不要优化代码,汇编指令保留原样。__volatile__volatile可以互相替换使用:#define __volatile__ volatile
  3. 内嵌汇编关键字asm volatile的括号内部第一部分是汇编代码,即前四句双引号代码。
    • 寄存器前会多一个%转义符号,即两个%(%%)
    • %数字表示后面输出部分、输入部分、破坏性描述部分的编号。按照这几部分里变量的出现顺序从0开始编号,具体来说%0表示变量val3%1表示变量val1%2表示变量val2(注意并不是按照前面c语言的声明顺序)
    • 注意%数字$数字区分,后者才是立即数的意思
  4. 先解释后面的输出输入部分,前面的汇编代码部分就能理解了。
    • 输出输入部分以:开头,这点和汇编代码部分不一样。
    • 大体的规则是:: "位置" (c上下文的变量名),其中位置里m表示memory,c表示ecx寄存器,d表示edx寄存器;通过上面说的%数字将汇编和C语言变量名进行绑定。=表示输出。
    • 没有输出/输入也要有:来占行占位。

因此,可以把这个模型的内嵌汇编看成是一个函数,第一部分是函数体,第二部分是返回值,第三部分是参数列表。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读