• 第三周学习笔记


    第三周学习笔记

    2018-10-24

    • C代码中嵌入汇编代码语法
    asm("statements": output_regs:input_regs:clobbered_regs);
    
          汇编语句模板      输出          输入          破坏描述部分
    

    eg:

    今日问题:

    • eax的值到底存数据还是地址 居然百度都没搜到答案。。。反思自己连百度都不会用
    • 破坏描述部分是什么?
      有时在进行某些操作时,除了要用到进行数据输入和输出的寄存器外,还要使用多个寄存器来保存中间计算结果,这样就难免会破坏原有寄存器的内容。如果希望GCC在编译时能够将这一点考虑进去。那么你就可以在“破坏描述部分”声明这些寄存器或内存。
      这种情况一般发生在一个寄存器出现在“汇编语句模板”,但却不是由输入或输出操作表达式所指定的,也不是在一些输入或输出操作表达式使用"r"、"g"约束时由GCC为其选择的,同时此寄存器被“汇编语句模板”中的指令修改,而这个寄存器只是供当前内嵌汇编临时使用的情况。比如:
      asm("movl %0, %%ebx" : : "a"(foo) : "%ebx");
      寄存器%ebx出现在“汇编语句模板”中,并且被movl指令修改,但却未被任何输入或输出操作表达式指定,所以你需要在“破坏描述部分”指定"%ebx",以让GCC知道这一点。
      因为你在输入或输出操作表达式所指定的寄存器,或当你为一些输入或输出操作表达式使用"r"、"g"约束,让GCC为你选择一个寄存器时,GCC对这些寄存器是非常清楚的——它知道这些寄存器是被修改的,你根本不需要在“破坏描述部分”再声明它们。但除此之外,GCC对剩下的寄存器中哪些会被当前的内嵌汇编修改一无所知。所以如果你真的在当前内嵌汇编语句中修改了它们,那么就最好“破坏描述部分”中声明它们,让GCC针对这些寄存器做相应的处理。否则有可能会造成寄存器的不一致,从而造成程序执行错误。
      在“破坏描述部分”中指定这些寄存器的方法很简单,你只需要将寄存器的名字使用双引号引起来。如果有多个寄存器需要声明,你需要在任意两个声明之间用逗号隔开。比如:
    __asm__("movl %0, %%ebx; popl %%ecx" : : "a"(foo) : "%ebx", "%ecx" );
    

    eg:

    • 注意:
      asm("mov %%eax, %%ebx" :)和__asm__("mov %eax, %ebx") 正确
      asm("mov %eax, %ebx" :)和__asm__("mov %%eax, %%ebx")不正确
      gcc编译的代码Windows可能运行有问题

    mykernel实验和三个法宝

    • 存储程序计算机:
      冯诺依曼体系
    • 中断:
      多道程序设计,CPU将当前eipespebp压到内核堆栈的另外一个堆栈里面去,把eip指向中断处理程序入口,保存现场,执行流的切换。CPU和内核代码共同实现了保存现场和恢复现场,周期性时钟中断
    • 堆栈:
      c语言程序运行必须的记录路径参数的空间,可以函数调用框架、传递参数、提供局部变量空间、保存返回地址等等

    函数调用堆栈

    • 建立函数调用框架
    push %ebp
    movl %esp,%ebp#调用者建立被调用者函数的堆栈框架
    

    //函数体//

    movl %ebp,%esp
    popl %ebp
    ret#拆除被调用者函数的堆栈框架
    

    实验楼mykernel实验指导(操作系统是如何工作的)

    cd LinuxKernel/linux-3.9.4
    rm -rf mykernel
    patch -p1 < ../mykernel_for_linux3.9.4sc.patch
    make allnoconfig
    make#当出现shiyanlou:~/ $才算编译完成
    qemu -kernel arch/x86/boot/bzImage
    



    执行代码效果图:

    2018-10-25

    • 立即寻址修改了寄存器的值为什么说没有和内存打交道?
      和同学讨论后认为寄存器在CPU里所以寄存器的值可能不在内存中。因此直接给寄存器赋值不和内存打交道。

    2018-10-26

    • 这个问题是四天前的问题,寄存器里存的到底是数值还是地址?
      今天看《庖丁解牛》发现EBX存的值是一个内存地址,也是一个数值。也就是说寄存器存的数值可以等于地址,寄存器存数值。
      但是这样一来,我觉得寄存器寻址和间接寻址一样了。按说应该有区别,区别是什么呢?。。。
    • esp指向的位置是不是就是esp存储的值作为地址指向的位置?
      看书发现是的。寄存器存储的数值减4=寄存器向下移一个单元
    • 销毁栈有时是popl %ebp,有时是popl %eip什么时候用哪个?
      ret 语句对应popl %eip,leave 语句对应popl %ebp
      movl %esp是什么意思?
    • 进程结构体是什么?
      进程是处于执行期的程序以及它所管理的资源(如打开的文件、挂起的信号、进程状态、地址空间等等)的总称。注意,程序并不是进程,实际上两个或多个进程不仅有可能执行同一程序,而且还有可能共享地址空间等资源。
    • asm volatile("movl %1,%%esp ")最后的 是什么意思?
      明天学下怎么用百度
  • 相关阅读:
    R语言学习笔记:向量化
    R语言笔记:快速入门
    再分析 返回值加引用&,const
    matlab 怎么保存plot的图 到指定文件夹
    不要在头文件中使用 using namespace std;
    散列表 (Hash table,也叫哈希表)
    重载操作符 operator overloading 学习笔记
    转 XMLHttpRequest().readyState的五种状态详解
    值得回味的基础知识理解加深
    完美解决fixed 水平居中问题
  • 原文地址:https://www.cnblogs.com/Ychancy/p/9859059.html
Copyright © 2020-2023  润新知