learningOS开源操作系统社区
  • 首页
  • 训练营
  • 明星学员
  • 共建单位
  • 项目实习
  • 问答论坛
登录
    Copyright © 2024 opencamp.ai All rights reserved.
    关于lab1课件上第31页“gcc内联汇编-Example 2”的解释
    匿名2023/07/31 19:52:01提问
      lab1student
    383

    应向勇老师要求,我整理了课后和老师讨论的结果。

    以下是原课件内容:

    看到这个example当时我有一个疑问,就是为什么要有中间的ebx和eax寄存器进行过渡,还要移到栈上进行再进行或操作。

    比如为什么不能是这样的?(简称“m1”)
    ;m1
    movl %cr0, 12(%esp)
    orl $-2147483648, 12(%esp)
    movl 12(%esp), %cr0
    或者这样(“m2”)
    ;m2
    movl %cr0, %ebx
    orl $-2147483648, %ebx
    movl %ebx, %cr0

    下面我先对每句c代码进行解释,并说明相对应的汇编代码:

    uint32_t cr0; // 无对应汇编,但gcc会给cr0分配存储单元,这里在栈上 -> 12(%esp)

    asm volatile ("movl %%cr0, %0\n" :"=r"(cr0));
    /*
    movl %cr0, %ebx
    movl %ebx, 12(%esp)
    将cr0寄存器内容移动到cr0变量 -> 12(%esp)
    之所以要两步是
    1. 因为cr0是控制寄存器,不能和栈(内存)直接操作,需要寄存器进行过渡(解释了m1的错误)
    2. 存到栈上是因为可能后面还需要用到cr0变量,所以把这临时变量分配到了栈上(解释了m2)
    3. 同时编译器为了忠实地实现每步内联汇编的内容,不再进一步优化代码
    */

    cr0 |= 0x80000000; // orl $-2147483648, 12(%esp),即把cr0最前面一位置1

    asm volatile ("movl %0, %%cr0\n" ::"r"(cr0));
    /*
    movl 12(%esp), %eax
    movl %eax, %cr0
    将变量cr0的内容移到cr0寄存器上,需要两步的原因同上
    */
    回答(2)
    即可发布评论
      推荐问答
        Simple Empty
        暂无数据