一. 乱糟糟的概念
指令集体系结构(ISA):一个处理器支持的指令和指令的字节级编码(每条指令被编码成由一个字节序列或多个字节序列组成的二进制格式)
不同的处理器家族有不同的ISA(例如Intel IA32和x86-64、IBM/Freescale Power和ARM处理器家族)有不同的ISA
同一处理器家族的不同处理器有相同的ISA
ISA为编译器编写者和处理器设计人员之间提供了一个概念抽象层:编译器编写者只需知道允许哪些指令,指令的字节级编码是什么;而处理器设计者只需建造出执行这些指令对应的二进制编码的处理器。
计算机科学的重要思想:用巧妙的方法在提高性能的同时又保持一个更简单、更抽象模型的功能。
数字硬件设计:基本构件块,如何连接以及操作,硬件控制语言(硬件系统控制部分的简单语言,用它来描述处理器设计)
二. 创建Y86-64指令集
较x86-64处理器支持的指令集而言,Y86-64指令集的数据类型、指令、寻址方式较少。
好处在于:字节级编码简单,CPU译码逻辑简单。
可以实现一些处理整数的程序。
在这一章中,我们会学习到如何用这个新定义出来的Y86-64指令集来设计处理器,并自己设计出来一个处理器,
CMU设计了一些研究和测试处理器设计的工具,包括:Y86-64的汇编器,以及运行Y86-64程序的模拟器,还有针对两个顺序处理器设计和一个流水线化处理设计的模拟器,设计的控制逻辑用HCL符号表示的文件来描述。
三. Y86-64指令集体系结构
程序员可见状态:Y86-64程序中每条指令都会读取和修改处理器状态的某些部分(程序寄存器、条件码、程序计数器、内存、状态码)。
程序员既可以指用汇编代码写程序的人,也可以是产生机器代码的编译器。
与x86-64区别:
- 15个程序寄存器RF(没有%r15),其中除了%rsp在出栈、入栈、调用和返回指令用作栈指针之外,其他寄存器无特殊含义(例如,没有调用者保存寄存器或者被调用者保存寄存器,返回值,参数等等)
- 3个一位条件码CC:ZF(零标志), SF(负标志), OF(溢出标志)
- 状态码Stat:表明程序执行的总体状态,指示是正常运行,还是出现了某种异常
Y86-64指令集只包括8字节整数操作,寻址方式较少,操作较少。
movq指令分成了4个不同的指令,显式指明了源操作数和目的操作数的类型:irmovq, rrmovq, mrmovq, rmmovq
i表示立即数,r表示寄存器,m表示内存。不允许从一个内存地址传送数据到另一个内存地址,也不支持将立即数传送到内存。
内存引用方式只支持简单的基址和偏移量形式,不支持第二变址寄存器和伸缩。
4个整数操作指令,addq,subq,andq,xorq,并且只对寄存器数据进行操作(x86-64允许对内存数据进行这些操作)
7个条转指令,jmp,jle,jl,je,jne,jge,jg,根据分支指令的类型和条件代码的设置来选择分支(条件与x86相同)
6个条件传送指令,cmovle,cmovl,cmove,cmovne,cmovge,cmovg,这些指令的格式与寄存器-寄存器传送指令rrmovq一样,但是只有当条件码满足所需要的约束时,才会更新目的寄存器值
call指令,ret指令,pushq指令,popq指令与x86相同
halt指令停止程序执行
指令编码(指令名称到8位2进制数的映射):长度从1个字节到10个字节不等,每条指令的第一个字节表明指令的类型:高4位是代码部分(0~0xB),低4位是功能部分(le<l<e<ne<ge<g)
寄存器标识符(寄存器到4位2进制数的映射)
寄存器指示符字节:指令后的操作数如果是寄存器类型,则第二个字节将会作为寄存器指示符字节,来指定一个或两个寄存器。
常数字:如果指令涉及到常数,例如irmovq指令的立即数数据,rmmovq和mrmovq指令的偏移量,jmp和call指定的地址,这四字节将会附加到前一或两个字节之后
指令集的一个重要性质就是字节编码必须有唯一的解释,这个性质保证了处理器可以无二义性地执行目标代码程序。