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

Merge pull request #566 from hopehook/master

fix: unrecognized instruction "NO_LOCAL_POINTERS"
This commit is contained in:
Xargin 2022-01-06 04:17:02 +08:00 committed by GitHub
commit 6b58756ab1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 7 additions and 5 deletions

View File

@ -61,7 +61,7 @@
- 算术相关(ADD/SUB/BUMP+/BUMP-)
- 跳转指令: 如果是条件跳转,寄存器中必须要有数据
主流的处理器也有类似的指令。除了基本的算术和逻辑算指令外,再配合有条件跳转指令就可以实现分支、循环等常见控制流结构了。
主流的处理器也有类似的指令。除了基本的算术和逻辑算指令外,再配合有条件跳转指令就可以实现分支、循环等常见控制流结构了。
下图是某一层的任务将输入数据的0剔除非0的数据依次输出右边部分是解决方案。

View File

@ -44,7 +44,7 @@ DATA ·Name+8(SB)/8,$6
## 3.3.2 全局变量
在Go语言中变量根据作用域和生命周期有全局变量和局部变量之分。全局变量是包一级的变量全局变量一般有着较为固定的内存地址声明周期跨越整个程序运行时间。而局部变量一般是函数内定义的的变量,只有在函数被执行的时间才被在栈上创建,当函数调用完成后将回收(暂时不考虑闭包对局部变量捕获的问题)。
在Go语言中变量根据作用域和生命周期有全局变量和局部变量之分。全局变量是包一级的变量全局变量一般有着较为固定的内存地址生命周期跨越整个程序运行时间。而局部变量一般是函数内定义的的变量,只有在函数被执行的时间才被在栈上创建,当函数调用完成后将回收(暂时不考虑闭包对局部变量捕获的问题)。
从Go汇编语言角度来看全局变量和局部变量有着非常大的差异。在Go汇编中全局变量和全局函数更为相似都是通过一个人为定义的符号来引用对应的内存区别只是内存中存放是数据还是要执行的指令。因为在冯诺伊曼系统结构的计算机中指令也是数据而且指令和数据存放在统一编址的内存中。因为指令和数据并没有本质的差别因此我们甚至可以像操作数据那样动态生成指令这是所有JIT技术的原理。而局部变量则需在了解了汇编函数之后才能通过SP栈空间来隐式定义。

View File

@ -289,6 +289,8 @@ L_END:
Go语言的编译器在生成函数的机器代码时会在开头插入一小段代码。因为sum函数也需要深度递归调用因此我们删除了NOSPLIT标志让汇编器为我们自动生成一个栈扩容的代码
```
#include "funcdata.h"
// func sum(n int) int
TEXT ·sum(SB), $16-16
NO_LOCAL_POINTERS
@ -359,7 +361,7 @@ func asmFunTwiceClosureBody() int
然后用Go汇编语言实现以上三个辅助函数
```s
```
#include "textflag.h"
TEXT ·ptrToFunc(SB), NOSPLIT, $0-16

View File

@ -4,9 +4,9 @@
## 3.7.1 系统调用
系统调用是操作系统外提供的公共接口。因为操作系统彻底接管了各种底层硬件设备因此操作系统提供的系统调用成了实现某些操作的唯一方法。从另一个角度看系统调用更像是一个RPC远程过程调用不过信道是寄存器和内存。在系统调用时我们向操作系统发送调用的编号和对应的参数然后阻塞等待系统调用地返回。因为涉及到阻塞等待因此系统调用期间的CPU利用率一般是可以忽略的。另一个和RPC地远程调用类似的地方是操作系统内核处理系统调用时不会依赖用户的栈空间一般不会导致爆栈发生。因此系统调用是最简单安全的一种调用了。
系统调用是操作系统外提供的公共接口。因为操作系统彻底接管了各种底层硬件设备因此操作系统提供的系统调用成了实现某些操作的唯一方法。从另一个角度看系统调用更像是一个RPC远程过程调用不过信道是寄存器和内存。在系统调用时我们向操作系统发送调用的编号和对应的参数然后阻塞等待系统调用地返回。因为涉及到阻塞等待因此系统调用期间的CPU利用率一般是可以忽略的。另一个和RPC地远程调用类似的地方是操作系统内核处理系统调用时不会依赖用户的栈空间一般不会导致爆栈发生。因此系统调用是最简单安全的一种调用了。
系统调用虽然简单,但是它是操作系统对外的接口,因此不同的操作系统调用规范可能有很大差异。我们先看看Linux在AMD64架构上的系统调用规范`syscall/asm_linux_amd64.s`文件中有注释说明:
系统调用虽然简单,但是它是操作系统对外的接口,因此不同的操作系统调用规范可能有很大差异。我们先看看Linux在AMD64架构上的系统调用规范`syscall/asm_linux_amd64.s`文件中有注释说明:
```go
//