Skip to content

Commit 4759482

Browse files
authored
Merge pull request #588 from iGmainC/master
自动生成 pdf
2 parents 5dfe633 + e56f76f commit 4759482

File tree

7 files changed

+112
-93
lines changed

7 files changed

+112
-93
lines changed

.github/workflows/book.yml

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ on:
1313
- closed
1414
jobs:
1515
deploy:
16-
runs-on: ubuntu-18.04
16+
runs-on: ubuntu-22.04
1717
steps:
1818
- name: Git checkout
1919
uses: actions/checkout@v2
@@ -23,14 +23,34 @@ jobs:
2323
with:
2424
mdbook-version: '0.4.10'
2525
# mdbook-version: 'latest'
26-
27-
- run: mdbook build
28-
26+
# 安装 build pdf 依赖和中文字体
27+
- run: sudo apt update && sudo apt install chromium-browser wget unzip fonts-wqy-microhei ttf-wqy-zenhei -y
28+
# 下载 mdbook-pdf 二进制文件, 编译太花时间了
29+
- run: |
30+
export mdbook_download_url=$(curl -s 'https://api.github.com/repos/HollowMan6/mdbook-pdf/releases?per_page=1&page=1' | python3 -c "import sys, json;import pprint;tmp=[print(x['browser_download_url']) if 'x86_64-unknown-linux-gnu' in x['name'] else None for x in json.load(sys.stdin)[0]['assets']]")
31+
wget $mdbook_download_url
32+
unzip mdbook*.zip
33+
rm mdbook*.zip
34+
chmod +x mdbook-pdf
35+
sudo mv mdbook-pdf /bin
36+
# build
37+
- run: |
38+
mdbook build
39+
mv book/pdf/output.pdf ./Go语言高级编程.pdf
40+
rm -r book/pdf/ && mv book/html/* book/ && rm -r book/html
41+
- name: Automatic Releases
42+
uses: marvinpinto/[email protected]
43+
with:
44+
# 将 pdf 文件 release
45+
repo_token: ${{ secrets.MY_DEPLOY_KEY }}
46+
automatic_release_tag: AutoBuild
47+
title: Go语言高级编程PDF
48+
files: "Go语言高级编程.pdf"
2949
- name: Deploy
3050
uses: peaceiris/actions-gh-pages@v3
3151
with:
3252
personal_token: ${{ secrets.MY_DEPLOY_KEY }}
33-
publish_dir: ./book
53+
publish_dir: ./book/
3454
publish_branch: gh-pages
3555
user_name: 'github-actions[bot]'
3656
user_email: 'github-actions[bot]@users.noreply.github.com'

book.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@ additional-js = ["js/custom.js", "js/bigPicture.js"]
1717
git-repository-url = "https://github.com/chai2010/advanced-go-programming-book"
1818
edit-url-template = "https://github.com/chai2010/advanced-go-programming-book/edit/master/{path}"
1919
git-repository-icon = "fa-github"
20+
21+
[output.pdf]

ch3-asm/ch3-01-basic.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ Go 汇编程序始终是幽灵一样的存在。我们将通过分析简单的 G
44

55
## 3.1.1 实现和声明
66

7-
Go 汇编语言并不是一个独立的语言,因为 Go 汇编程序无法独立使用。Go 汇编代码必须以 Go 包的方式组织,同时包中至少要有一个 Go 语言文件用于指明当前包名等基本包信息。如果 Go 汇编代码中定义的变量和函数要被其它 Go 语言代码引用,还需要通过 Go 语言代码将汇编中定义的符号声明出来。用于变量的定义和函数的定义 Go 汇编文件类似于 C 语言中的. c 文件,而用于导出汇编中定义符号的 Go 源文件类似于 C 语言的. h 文件。
7+
Go 汇编语言并不是一个独立的语言,因为 Go 汇编程序无法独立使用。Go 汇编代码必须以 Go 包的方式组织,同时包中至少要有一个 Go 语言文件用于指明当前包名等基本包信息。如果 Go 汇编代码中定义的变量和函数要被其它 Go 语言代码引用,还需要通过 Go 语言代码将汇编中定义的符号声明出来。用于变量的定义和函数的定义 Go 汇编文件类似于 C 语言中的 `.c` 文件,而用于导出汇编中定义符号的 Go 源文件类似于 C 语言的 `.h` 文件。
88

99
## 3.1.2 定义整数变量
1010

1111
为了简单,我们先用 Go 语言定义并赋值一个整数变量,然后查看生成的汇编代码。
1212

13-
首先创建一个 pkg.go 文件,内容如下:
13+
首先创建一个 `pkg.go` 文件,内容如下:
1414

1515
```go
1616
package pkg
@@ -59,7 +59,7 @@ GLOBL ·Id, $8
5959

6060
现在已经初步完成了用汇编定义一个整数变量的工作。
6161

62-
为了便于其它包使用该 Id 变量,我们还需要在 Go 代码中声明该变量,同时也给变量指定一个合适的类型。修改 pkg.go 的内容如下:
62+
为了便于其它包使用该 Id 变量,我们还需要在 Go 代码中声明该变量,同时也给变量指定一个合适的类型。修改 `pkg.go` 的内容如下:
6363

6464
```go
6565
package pkg
@@ -69,7 +69,7 @@ var Id int
6969

7070
现状 Go 语言的代码不再是定义一个变量,语义变成了声明一个变量(声明一个变量时不能再进行初始化操作)。而 Id 变量的定义工作已经在汇编语言中完成了。
7171

72-
我们将完整的汇编代码放到 pkg_amd64.s 文件中:
72+
我们将完整的汇编代码放到 `pkg_amd64.s` 文件中:
7373

7474
```
7575
#include "textflag.h"
@@ -86,7 +86,7 @@ DATA ·Id+6(SB)/1,$0x00
8686
DATA ·Id+7(SB)/1,$0x00
8787
```
8888

89-
文件名 pkg_amd64.s 的后缀名表示 AMD64 环境下的汇编代码文件。
89+
文件名 `pkg_amd64.s` 的后缀名表示 AMD64 环境下的汇编代码文件。
9090

9191
虽然 pkg 包是用汇编实现,但是用法和之前的 Go 语言版本完全一样:
9292

@@ -107,7 +107,7 @@ func main() {
107107

108108
在前一个例子中,我们通过汇编定义了一个整数变量。现在我们提高一点难度,尝试通过汇编定义一个字符串变量。虽然从 Go 语言角度看,定义字符串和整数变量的写法基本相同,但是字符串底层却有着比单个整数更复杂的数据结构。
109109

110-
实验的流程和前面的例子一样,还是先用 Go 语言实现类似的功能,然后观察分析生成的汇编代码,最后用 Go 汇编语言仿写。首先创建 pkg.go 文件,用 Go 语言定义字符串:
110+
实验的流程和前面的例子一样,还是先用 Go 语言实现类似的功能,然后观察分析生成的汇编代码,最后用 Go 汇编语言仿写。首先创建 `pkg.go` 文件,用 Go 语言定义字符串:
111111

112112
```go
113113
package pkg
@@ -128,7 +128,7 @@ go.string."gopher" SRODATA dupok size=6
128128

129129
输出中出现了一个新的符号 go.string."gopher",根据其长度和内容分析可以猜测是对应底层的 "gopher" 字符串数据。因为 Go 语言的字符串并不是值类型,Go 字符串其实是一种只读的引用类型。如果多个代码中出现了相同的 "gopher" 只读字符串时,程序链接后可以引用的同一个符号 go.string."gopher"。因此,该符号有一个 SRODATA 标志表示这个数据在只读内存段,dupok 表示出现多个相同标识符的数据时只保留一个就可以了。
130130

131-
而真正的 Go 字符串变量 Name 对应的大小却只有 16 个字节了。其实 Name 变量并没有直接对应 “gopher” 字符串,而是对应 16 字节大小的 reflect.StringHeader 结构体:
131+
而真正的 Go 字符串变量 `Name` 对应的大小却只有 16 个字节了。其实 `Name` 变量并没有直接对应 “gopher” 字符串,而是对应 16 字节大小的 reflect.StringHeader 结构体:
132132

133133
```go
134134
type reflect.StringHeader struct {
@@ -137,9 +137,9 @@ type reflect.StringHeader struct {
137137
}
138138
```
139139

140-
从汇编角度看,Name 变量其实对应的是 reflect.StringHeader 结构体类型。前 8 个字节对应底层真实字符串数据的指针,也就是符号 go.string."gopher" 对应的地址。后 8 个字节对应底层真实字符串数据的有效长度,这里是 6 个字节。
140+
从汇编角度看,`Name` 变量其实对应的是 `reflect.StringHeader` 结构体类型。前 8 个字节对应底层真实字符串数据的指针,也就是符号 go.string."gopher" 对应的地址。后 8 个字节对应底层真实字符串数据的有效长度,这里是 6 个字节。
141141

142-
现在创建 pkg_amd64.s 文件,尝试通过汇编代码重新定义并初始化 Name 字符串:
142+
现在创建 pkg_amd64.s 文件,尝试通过汇编代码重新定义并初始化 `Name` 字符串:
143143

144144
```
145145
GLOBL ·NameData(SB),$8
@@ -152,7 +152,7 @@ DATA ·Name+8(SB)/8,$6
152152

153153
因为在 Go 汇编语言中,go.string."gopher" 不是一个合法的符号,因此我们无法通过手工创建(这是给编译器保留的部分特权,因为手工创建类似符号可能打破编译器输出代码的某些规则)。因此我们新创建了一个 ·NameData 符号表示底层的字符串数据。然后定义 ·Name 符号内存大小为 16 字节,其中前 8 个字节用 ·NameData 符号对应的地址初始化,后 8 个字节为常量 6 表示字符串长度。
154154

155-
当用汇编定义好字符串变量并导出之后,还需要在 Go 语言中声明该字符串变量。然后就可以用 Go 语言代码测试 Name 变量了:
155+
当用汇编定义好字符串变量并导出之后,还需要在 Go 语言中声明该字符串变量。然后就可以用 Go 语言代码测试 `Name` 变量了:
156156

157157
```go
158158
package main

0 commit comments

Comments
 (0)