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

Merge pull request #123 from fuwensun/pr3-5

ch3-03-fix typo
This commit is contained in:
chai2010 2018-06-26 19:07:40 +08:00 committed by GitHub
commit 3986af7356
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -29,14 +29,14 @@ $(3&1)<<2 // == $4
## 全局变量 ## 全局变量
在Go语言中变量根据作用域和生命周期有全局变量和局部变量之分。全局变量是包一级的变量全局变量一般有着较为固定的内存地址声明周期跨越整个程序运行时间。而局部变量一般是函数内定义的的变量只有在函数被执行的时间才能被创建当函数完成时将回收(暂时不考虑闭包对局部变量捕获的问题)。 在Go语言中变量根据作用域和生命周期有全局变量和局部变量之分。全局变量是包一级的变量全局变量一般有着较为固定的内存地址声明周期跨越整个程序运行时间。而局部变量一般是函数内定义的的变量只有在函数被执行的时间才能被创建当函数完成时将回收暂时不考虑闭包对局部变量捕获的问题
从Go汇编语言角度来看变量和局部变量也大的差异。在Go汇编中全局变量和全局函数更为相似都是通过一个为定义的符号来引用对应的内存区别只是内存中存放是数据还是要执行的指令。因为在冯诺伊曼系统结构的计算机中指令也是数据而且指令和数据存放在统一编址的内存中因此指令和数据并没有本质的差别——我们甚至可以像操作数据那样动态生成指令。而局部变量则需了解了汇编函数之后通过SP栈空间来隐式定义。 从Go汇编语言角度来看局变量和局部变量也大的差异。在Go汇编中全局变量和全局函数更为相似都是通过一个为定义的符号来引用对应的内存区别只是内存中存放是数据还是要执行的指令。因为在冯诺伊曼系统结构的计算机中指令也是数据而且指令和数据存放在统一编址的内存中因此指令和数据并没有本质的差别——我们甚至可以像操作数据那样动态生成指令。而局部变量则需了解了汇编函数之后通过SP栈空间来隐式定义。
![](../images/ch3-pkg-var-decl-01.ditaa.png) ![](../images/ch3-pkg-var-decl-01.ditaa.png)
在Go汇编语言中内存是通过SB伪寄存器定位。SB是Static base pointer的缩写意为静态内存的开始地址。所有的静态全局符号通可以通过SB加一个偏移量定位而我们定义的符号其实就是相对于SB内存开始地址偏移量。对于SB伪寄存器全局变量和全局函数的符号并没有任何区别。 在Go汇编语言中内存是通过SB伪寄存器定位。SB是Static base pointer的缩写意为静态内存的开始地址。所有的静态全局符号通可以通过SB加一个偏移量定位而我们定义的符号其实就是相对于SB内存开始地址偏移量。对于SB伪寄存器全局变量和全局函数的符号并没有任何区别。
要定义全局变量,首先要声明一个变量对应的符号,以及变量对应的内存大小。导出变量符号的语法如下: 要定义全局变量,首先要声明一个变量对应的符号,以及变量对应的内存大小。导出变量符号的语法如下:
@ -50,7 +50,7 @@ GLOBL汇编指令用于定义名为symbol的变量变量对应的内存宽度
GLOBL ·count(SB),$4 GLOBL ·count(SB),$4
``` ```
其中符号`·count`以中点开头表示是当前包的变量,最终符号名为被展开为`path/to/pkg.count`。count变量的大小是4个字节常量必须以$美元符号开头。内存的宽度必须是2的指数倍编译器最终会保证变量的实地址对齐到机器字宽度。需要注意的是在Go汇编中我们无法为count变量指定具体的类型。在汇编中定义全局变量时我们关心变量的名字和内存大小变量最终的类型只能在Go语言中声明。 其中符号`·count`以中点开头表示是当前包的变量,最终符号名为被展开为`path/to/pkg.count`。count变量的大小是4个字节常量必须以$美元符号开头。内存的宽度必须是2的指数倍编译器最终会保证变量的实地址对齐到机器字宽度。需要注意的是在Go汇编中我们无法为count变量指定具体的类型。在汇编中定义全局变量时我们关心变量的名字和内存大小变量最终的类型只能在Go语言中声明。
变量定义之后我们可以通过DATA汇编指令指定对应内存中的数据语法如下 变量定义之后我们可以通过DATA汇编指令指定对应内存中的数据语法如下
@ -75,7 +75,7 @@ DATA ·count+0(SB)/4,$0x01020304
因为X86处理器是小端序因此用十六进制0x01020304初始化全部的4个字节和用1、2、3、4逐个初始化4个字节是一样的效果。 因为X86处理器是小端序因此用十六进制0x01020304初始化全部的4个字节和用1、2、3、4逐个初始化4个字节是一样的效果。
最后还需要在Go语言中声明对应的变量和C语言头文件声明变量的作用类似这样垃圾回收器会更加变量的类型来管理其中的指针相关的内存数据。 最后还需要在Go语言中声明对应的变量和C语言头文件声明变量的作用类似这样垃圾回收器会根据变量的类型来管理其中的指针相关的内存数据。
## 变量的布局 ## 变量的布局