程序的机器级表示

原创 2017年04月29日 09:25:40

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. 限制可执行代码的存储区域

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

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

程序的机器级表示

简介 简单介绍有关于机器如何表示数据,如何存储数据,如何访问和操作数据,如何控制被执行操作的顺序

《深入理解计算机系统》第3章 程序的机器级表示

要点一:数据格式(c语言在IA32中表示的大小) 要点二:IA32的整数寄存器 要点三:操作数指示符 要点五:数据传送指令 要点六:算术和逻辑操作 要点七:特殊的算术操作...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

深入理解计算机系统(笔记):程序的机器级表示

分析高级语言编译后生成的汇编语言。 1. 程序编码 运行如下命令得到C语言的汇编代码: unix> gcc -O1 -S code.c gcc -c选项编译源文件生产目标文件code.o: u...

程序的机器级表示(2)--IA32汇编代码

IA32的整数寄存器一个IA32中央处理单元(CPU)包含一组8个储存32位值的寄存器。这些寄存器储存整数数据和指针。

程序的机器级表示

本篇文章用C语言与汇编语言对比,简单的介绍下高级语言到汇编语言的过程。

20170226听课笔记(程序的机器级表示)

上节课讲了递归、堆栈,及每一个函数的栈帧在堆栈中是怎么排列的,但并未深入到机器级的层次,对 CPU 来说,它到底是怎么维持这个堆栈的,以及上节课提到的 EPB 和 ESP 到底是如何处理的。 预备知识...

程序机器级表示

一个函数调用包括将数据(包括参数和返回值)和控制从代码一部分传到另一部分。还包括对函数内局部变量分配空间,并在退出时释放空间。  其中,转移控制到过程 和 从过程转移出控制——使用指令;局部变量的分配...
  • isunn
  • isunn
  • 2014-10-09 14:52
  • 401

程序的机器级表示(前篇)

机器代码,汇编代码、栈、寄存器

程序的机器级表示(IA32,AT&T,二,控制)

前言上篇博客我们讲到了一些基本的算术逻辑指令以及数据传送指令 今天我们主要论述一下标志位,跳转指令,以及跳转表。常用的标志位以及访问指令 CF(Carry Flag)进/借位标志 当发生进借...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)