程序的机器级表示

2017年4月趁着临近毕业时间比较充裕,就买了一本深入理解计算机系统(第三版),这本书的第二版之前浅浅的读过一遍只对里面的编译与链接章节印象深刻,其他章节对我来说完全陌生,我深知这本书的好,于是重新拾起这本书。为了加深自己的记忆就开始写博客记录自己的读书笔记。

第三章 程序的机器级表示

  • gcc4.8 引入-Og选项,使得生成的代码更符合原始程序的结构。

  • 传送类指令的两个操作数不能指向内存位置。

  • 任何更新低位4字节的指令都会把高位字节设置为0,例如: 通过movl将立即数移动到目的寄存器中会将寄存器的高四位设置为0。

  • cltq指令没有操作数,该指令的含义是将%eax作为源,%rax作为符号扩展结果的目的地。

  • leaq指令是用来加载有效地址的,但是通常被用来进行简单的算术操作。

  • cqto指令不需要操作数,直接将%rax中的符号位并将其复制到%rdx的所有位中。

  • 基于控制的条件转移 vs 基于数据的条件转移

    基于控制的条件转移当条件满足时程序沿着一条执行路径走,否则走另外一条执行路径,这种机制简单而通用,但是在现代处理器上可能会非常低效,一种替代策略就是使用基于数据的条件转移,这种方法计算一个条件操作的两种结果,然后再根据条件是否满足从中取一个。这样就可以简单的使用条件传送指令实现了,条件传送指令更符合现代处理器的特性。例如: cmovge指令

  • 在现代处理器下为什么基于控制的条件转移没有基于数据的条件转移性能好?

    基于控制的条件转移导致处理器无法并行的执行条件后面的指令,需要进行指令流的预测,预先执行预测的指令,如果预测成功了,那么事半功倍,如果预测失败了就需要丢弃已经执行的指令结果,然后重新执行新的指令,当预测的准确率不高的情况下会导致性能下降,而基于数据的条件转移就不会出现这种情况。

  • 位操作判断一个数的二进制中存在奇数还是偶数个1

    long func(unsigned long x) {
    long val = 0;
    while(x) {
      val ^= x;
      x >>= 1;
    }
    return x & 0x1;
    }
  • 分支预测错误的处罚

    1. 假设预测错误的概率是p
    2. 如果没有预测错误的情况下,代码的执行时间为T-OK
    3. 预测错误的处罚为T-MP

    执行代码的平均时间如下:

    T-AVG = (1-p)T-OK + p(T-OK + T-MP)

  • 寄存器使用惯例,分为两类,一类是被调用者保存寄存器,另外一类是调用者保存寄存器

    1. %rbx%rbp、 和%r12~%r15 被调用者保存寄存器。被调用的函数在使用这些寄存器之前需要先保存这些寄存器的值。
    2. 所有其他的寄存器,除了栈指针%rsp,都分类为调用者寄存器。也就是任何函数都可以修改它,可以理解为P在这些寄存器里面存放了数据,然后调用Q,Q是可以随便修改这些寄存器的,所以P有责任在调用之前将这些数据保存起来。
  • 数据对齐机制

    ​ 对于大多数x86-64指令来说,保存数据对齐是能够提高效率,但是不会影响程序的行为,另一方面如果数据没有对齐某些型号的Intel和AMD处理器对于实现多媒体操纵的SSE指令,就无法正确执行了。此外地址对齐还有益于提高内存系统的性能,减少CPU读取内存数据的周期。

  • 缓冲区溢出攻击

    ​ 因为局部变量是存放在堆栈上的,而堆栈上还存放了返回地址,别有用心的人可以通过溢出局部变量的存储空间,将恶意代码的指令地址覆盖掉保存在栈上的返回地址,从而执行一些恶意的代码。或者是直接将一些恶意代码的二进制通过溢出局部变量的存储空间使得这些代码保存在堆栈上被执行。现代的编译器实现了很多机制,以避免遭受这样的攻击,限制入侵者通过缓冲区溢出攻击获得系统控制的方式。

    1. 栈随机化属于地址空间布局随机化简称为ASLR

      ​ 通过将栈的位置在程序每次运行时都有变化,实现的方式可以是在程序开始时预先在栈上分配一段0~N字节之间的随即大笑的空间。

    2. 堆栈保护机制

      ​ 在栈帧中任何局部缓冲区与栈状态之间存储一个特殊的金丝雀(canary)值,在恢复寄存器状态和从函数返回的时候都会去检查这个金丝雀值是否被改变了,如果被改变了程序就会异常终止。(gcc 的-fno-stack-protector选项)

    3. 限制可执行代码的存储区域

      ​ 限制哪些内存区域能够存放可执行代码,在典型的程序中,只有保存编译器产生的代码的那部分内存才需要可执行的,其他部分可以被限制为只允许读和写。

你可能感兴趣的:(生活-读书-大事记,程序员基础)