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

Merge pull request #124 from fuwensun/pr3-6

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

View File

@ -121,7 +121,7 @@ bool类型的内存大小为1个字节。并且汇编中定义的变量需要手
## int型变量
所有的整数类型均有类似的定义的方式,比较大的差异是整数类型的内存大和整数是否是有符号。下面是声明的int32和uint32类型变量
所有的整数类型均有类似的定义的方式,比较大的差异是整数类型的内存大和整数是否是有符号。下面是声明的int32和uint32类型变量
```go
var int32Value int32
@ -145,13 +145,13 @@ DATA ·uint32Value(SB)/4,$0x01020304 // 第1-4字节
## float型变量
Go汇编语言通用无法取区分变量是否是浮点数类型,之上相关的浮点数机器指令会将变量当作浮点数处理。Go语言的浮点数遵循IEEE754标准有float32单精度浮点数和float64双精度浮点数之分。
Go汇编语言通常无法取区分变量是否是浮点数类型,与之相关的浮点数机器指令会将变量当作浮点数处理。Go语言的浮点数遵循IEEE754标准有float32单精度浮点数和float64双精度浮点数之分。
IEEE754标准中最高位1bit为符号位然后是指数位指数为采用移码格式表示然后是有效数部分其中小数点左边的一个bit位被省略。下图是IEEE754中float32类型浮点数的bit布局
![](../images/ch3-03-ieee754.jpg)
IEEE754浮点数还有一些奇妙的特性比如有正负两个0除了无穷大和无穷小还有inf非数;同时如果两个浮点数如果有序那么bit对应的整数也是有序的。
IEEE754浮点数还有一些奇妙的特性比如有正负两个0除了无穷大和无穷小Inf还有非数NaN同时如果两个浮点数有序那么bit对应的整数也是有序的。
下面是在Go语言中先声明两个浮点数如果没有在汇编中定义变量那么声明的同时也会定义变量
@ -171,7 +171,7 @@ GLOBL ·float64Value(SB),$8
DATA ·float64Value(SB)/4,$0x01020304 // bit 方式初始化
```
我们在上一节精简的算术指令中都是针对整数,如果要通过整数指令处理浮点数加减法必须根据浮点数的运算规则进行:先对齐小数点,然后进行整数加减法,最后再对结果进行归一化并处理精度舍入问题。
我们在上一节精简的算术指令中都是针对整数,如果要通过整数指令处理浮点数加减法必须根据浮点数的运算规则进行:先对齐小数点,然后进行整数加减法,最后再对结果进行归一化并处理精度舍入问题。
## string类型变量
@ -184,7 +184,7 @@ type reflect.StringHeader struct {
}
```
在amd64环境中StringHeader有16个字节大因此我们先在Go代码声明字符串比阿里然后在汇编中定义一个16字节大小的变量
在amd64环境中StringHeader有16个字节大因此我们先在Go代码声明字符串变量然后在汇编中定义一个16字节大小的变量
```go
var helloworld string
@ -262,7 +262,7 @@ GLOBL ·ch(SB),$8 // var ch chan int
DATA ·ch+0(SB)/8,$0
```
在runtime包其实为汇编提供了一些辅助函数。比如在汇编中可以通过runtime.makemap和runtime.makechan内部函数来创建map和chan变量。辅助函数的签名如下
其实在runtime包中为汇编提供了一些辅助函数。比如在汇编中可以通过runtime.makemap和runtime.makechan内部函数来创建map和chan变量。辅助函数的签名如下
```go
func makemap(mapType *byte, hint int, mapbuf *any) (hmap map[any]any)
@ -276,7 +276,7 @@ func makechan(chanType *byte, size int) (hchan chan any)
Go语言的标识符可以由绝对的包路径加标识符本身定位因此不同包中的标识符即使同名也不会有问题。Go汇编是通过特殊的符号来表示斜杠和点符号因为这样可以简化汇编器词法扫描部分代码的编写只要通过字符串替换就可以了。
下面是汇编中常见的几种标识符的使用方式(通也适用于函数标识符):
下面是汇编中常见的几种标识符的使用方式(通也适用于函数标识符):
```
GLOBL ·pkg_name1(SB),$1
@ -284,7 +284,7 @@ GLOBL main·pkg_name2(SB),$1
GLOBL my/pkg·pkg_name(SB),$1
```
此外Go汇编中可以可以定义仅当前文件可以访问的私有标识符类似C语言中文件内static修饰的变量`<>`为后缀名:
此外Go汇编中可以定义仅当前文件可以访问的私有标识符类似C语言中文件内static修饰的变量`<>`为后缀名:
```
GLOBL file_private<>(SB),$1
@ -292,7 +292,7 @@ GLOBL file_private<>(SB),$1
这样可以减少私有标识符对其它文件内标识符命名的干扰。
此外Go汇编语言还在"textflag.h"文件定义了一些标志。其中用于变量的标志有DUPOK、RODATA和NOPTR几个。DUPOK表示该变量对应的标识符可能有多个在链接时只选择其中一个即可一般用于合并相同的常量字符串减少重复数据占用的空间。RODATA标志表示将变量定义在只读内存段因此后续任何对此变量的修改操作将导致异常panic也无法捕获。NOPTR则表示此变量的内部不含指针数据让垃圾回收器忽略对该变量的扫描。如果变量已经在Go代码中声明过的话Go编译器会自动分析出该变量是否包含指针这种时候可以不用手写NOPTR标志。
此外Go汇编语言还在"textflag.h"文件定义了一些标志。其中用于变量的标志有DUPOK、RODATA和NOPTR几个。DUPOK表示该变量对应的标识符可能有多个在链接时只选择其中一个即可一般用于合并相同的常量字符串减少重复数据占用的空间。RODATA标志表示将变量定义在只读内存段因此后续任何对此变量的修改操作将导致异常panic也无法捕获。NOPTR则表示此变量的内部不含指针数据让垃圾回收器忽略对该变量的扫描。如果变量已经在Go代码中声明过的话Go编译器会自动分析出该变量是否包含指针这种时候可以不用手写NOPTR标志。
下面是通过汇编来定义一个只读的int类型的变量