1
0
mirror of https://github.com/chai2010/advanced-go-programming-book.git synced 2025-05-24 04:22:22 +00:00

ch3-02: 完善

This commit is contained in:
chai2010 2018-06-01 08:29:44 +08:00
parent 2843948025
commit df0ba9beb0
3 changed files with 31 additions and 1 deletions

View File

@ -80,7 +80,37 @@ LOOP:
首先通过INBOX指令读取一个数据包然后判断包裹的数据是否为0如果是0的话就跳转到开头继续读取下一个数据包否则将输出数据包然后再跳转到开头。以此循环无休止地处理数据包裹直到任务完成晋升到更高一级的岗位然后处理类似的但更复杂的任务。
## 精简X86指令集
## 精简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类型、或不同的操作系统环境、或不同的汇编工具链下是不可移植的。而这种不可移植性正是汇编语言普及的一个极大的障碍。虽然CPU指令集的差异是导致不好移植的较大因素但是汇编语言的相关工具链对此也有不可推卸的责任。而源自Plan9的Go汇编语言对此做了一定的改进首先Go汇编语言在相同CPU架构上是完全一致的也就是屏蔽了操作系统的差异同时Go汇编语言将一些基础并且类似的指令抽象为相同名字的伪指令从而减少不同CPU架构下汇编代码的差异当然寄存器名字和数量的差异是一直存在的。本节的目的也是找出一个较小的精简指令集以简化Go汇编语言学习的目的。
X86是一个极其复杂的系统有人统计x86-64中指令有将近一千个之多。不仅仅如此X86中的很多单个指令的功能也非常强大比如有论文证明了仅仅一个MOV指令就可以构成一个图灵完备的系统。以上这是两种极端情况太多的指令和太少的指令都不利于汇编程序的编写。因此我们将尝试精简出一个X86-64指令集以便于Go汇编语言的学习。
再次之前我们件简单看下X86和X86-64的结构图
![](../images/ch3-02-x86.jpg)
![](../images/ch3-02-x86-64.jpg)
<!-- TODO: 合并两个图 -->
其中最重要的部分是指令指针、标题标志和通用寄存器部分。对比可以发现X86和X86-64结构还是比较相似的只是64位CPU的通用寄存器更多一些而已。因为历史原因X86中的前8个通用寄存器并不是以数字顺序命名它们是以AX、BX、CX、DX、SI、DI、BP、SP方式命名。而X86-64新增加的8个通用寄存器则是以R8-R15方式命名。其中R0-R7并不是通用寄存器它们之上X87开始引入的MMX指令专有的寄存器。在通用寄存器中BP和SP是两个比较特殊的寄存器其中BP用于记录当前函数帧的开始位置和函数调用相关的指令会隐式地影响SP的值SP则对应当前栈指针的位置和栈相关的指令会隐式地影响SP的值。
我们可以尝试用一个结构体来类比简化的X86结构
```go
type X86CPU struct {
Flag uint
AX, BX, CX, DX int
SP uintptr
IP uintptr
Memery [...]int
}
```
其中Flag对应计算机的内部状态标志我们一般不会直接读取Flag只有在一些特殊的场景才会需要直接操作比如操作系统中进程切换时保存和恢复状态
TODO

BIN
images/ch3-02-x86-64.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
images/ch3-02-x86.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB