3.2.3 X86-64体系结构
X86其实是是80X86的简称(后面三个字母),包括Intel 8086、80286、80386以及80486等指令集合,因此其架构被称为x86架构。x86-64是AMD公司于1999年设计的x86架构的64位拓展,向后兼容于16位及32位的x86架构。X86-64目前正式名称为AMD64,也就是Go语言中GOARCH环境变量指定的AMD64。如果没有特殊说明的话,本章中的汇编程序都是针对64位的X86-64环境。
在使用汇编语言之前必须要了解对应的CPU体系结构。下面是X86/AMD架构图:
左边是内存部分是常见的内存布局。其中text一般对应代码段,用于存储要执行指令数据,代码段一般是只读的。然后是rodata和data数据段,数据段一般用于存放全局的数据,其中rodata是只读的数据段。而heap段则用于管理动态的数据,stack段用于管理每个函数调用时相关的数据。在汇编语言中一般重点关注text代码段和data数据段,因此Go汇编语言中专门提供了对应TEXT和DATA命令用于定义代码和数据。
中间是X86提供的寄存器。寄存器是CPU中最重要的资源,每个要处理的内存数据原则上需要先放到寄存器中才能由CPU处理,同时寄存器中处理完的结果需要再存入内存。X86中除了状态寄存器FLAGS和指令寄存器IP两个特殊的寄存器外,还有AX、BX、CX、DX、SI、DI、BP、SP几个通用寄存器。在X86-64中又增加了八个以R8-R15方式命名的通用寄存器。因为历史的原因R0-R7并不是通用寄存器,它们只是X87开始引入的MMX指令专有的寄存器。在通用寄存器中BP和SP是两个比较特殊的寄存器:其中BP用于记录当前函数帧的开始位置,和函数调用相关的指令会隐式地影响BP的值;SP则对应当前栈指针的位置,和栈相关的指令会隐式地影响SP的值;而某些调试工具需要BP寄存器才能正常工作。
右边是X86的指令集。CPU是由指令和寄存器组成,指令是每个CPU内置的算法,指令处理的对象就是全部的寄存器和内存。我们可以将每个指令看作是CPU内置标准库中提供的一个个函数,然后基于这些函数构造更复杂的程序的过程就是用汇编语言编程的过程。
学员评价