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

ch3-03: 重构内容

This commit is contained in:
chai2010 2018-07-21 14:22:51 +08:00
parent 91cc585681
commit 05bfe78edc

View File

@ -1,6 +1,6 @@
# 3.3. 常量和全局变量
程序中的一切变量的初始值都直接或间接地依赖常量或常量表达式生成。在Go语言中很多变量是默认零值初始化的但是Go汇编中定义的变量最好还是手工通过常量初始化。有了常量之后就可以定义全局变量并使用常量组成的表达式初始化全部变量。本节将简单讨论Go汇编语言中常量和全局变量的用法。
程序中的一切变量的初始值都直接或间接地依赖常量或常量表达式生成。在Go语言中很多变量是默认零值初始化的但是Go汇编中定义的变量最好还是手工通过常量初始化。有了常量之后就可以衍生定义全局变量,并使用常量组成的表达式初始化其它各种变量。本节将简单讨论Go汇编语言中常量和全局变量的用法。
## 常量
@ -26,12 +26,27 @@ $(3&1)<<2 // == $4
其中常量表达式中运算符的优先级和Go语言保持一致。
Go汇编语言中的常量其实不仅仅只有编译时常量还包含运行时常量。比如包中全局的变量和全局函数在运行时地址也是固定不变的这里地址不会变量的包变量和函数的地址也是一种汇编常量。
下面是本章第一节用汇编定义的字符串代码:
```
GLOBL ·NameData(SB),$8
DATA ·NameData(SB)/8,$"gopher"
GLOBL ·Name(SB),$16
DATA ·Name+0(SB)/8,$·NameData(SB)
DATA ·Name+8(SB)/8,$6
```
其中`$·NameData(SB)`也是以$美元符号为前缀因此也可以将它看作是一个常量它对应的是NameData包变量的地址。在汇编指令中我们也可以通过LEA指令来获取NameData变量的地址。
## 全局变量
在Go语言中变量根据作用域和生命周期有全局变量和局部变量之分。全局变量是包一级的变量全局变量一般有着较为固定的内存地址声明周期跨越整个程序运行时间。而局部变量一般是函数内定义的的变量只有在函数被执行的时间才能被创建当函数完成时将回收暂时不考虑闭包对局部变量捕获的问题
在Go语言中变量根据作用域和生命周期有全局变量和局部变量之分。全局变量是包一级的变量全局变量一般有着较为固定的内存地址声明周期跨越整个程序运行时间。而局部变量一般是函数内定义的的变量只有在函数被执行的时间才被在栈上创建,当函数调用完成后将回收(暂时不考虑闭包对局部变量捕获的问题)。
从Go汇编语言角度来看全局变量和局部变量也有大的差异。在Go汇编中全局变量和全局函数更为相似都是通过一个人为定义的符号来引用对应的内存区别只是内存中存放是数据还是要执行的指令。因为在冯诺伊曼系统结构的计算机中指令也是数据而且指令和数据存放在统一编址的内存中因此指令和数据并没有本质的差别——我们甚至可以像操作数据那样动态生成指令。而局部变量则需了解了汇编函数之后通过SP栈空间来隐式定义。
从Go汇编语言角度来看全局变量和局部变量有着非常大的差异。在Go汇编中全局变量和全局函数更为相似都是通过一个人为定义的符号来引用对应的内存区别只是内存中存放是数据还是要执行的指令。因为在冯诺伊曼系统结构的计算机中指令也是数据而且指令和数据存放在统一编址的内存中。因为指令和数据并没有本质的差别,因此我们甚至可以像操作数据那样动态生成指令这是所有JIT技术的原理。而局部变量则需了解了汇编函数之后,才能通过SP栈空间来隐式定义。
![](../images/ch3-pkg-var-decl-01.ditaa.png)