From 116a134d3b93d2780685ac08d55b968829788b01 Mon Sep 17 00:00:00 2001 From: chai2010 Date: Sat, 21 Jul 2018 12:46:15 +0800 Subject: [PATCH] =?UTF-8?q?ch3-01:=20=E5=AE=8C=E5=96=84=E6=96=87=E5=AD=97?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ch3-asm/ch3-01-basic.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/ch3-asm/ch3-01-basic.md b/ch3-asm/ch3-01-basic.md index 35f4f22..904f8fc 100644 --- a/ch3-asm/ch3-01-basic.md +++ b/ch3-asm/ch3-01-basic.md @@ -220,10 +220,6 @@ DATA ·Name+16(SB)/8,$"gopher" 前面的例子已经展示了如何通过汇编定义整型和字符串类型变量。我们现在将尝试用汇编实现函数,然后输出一个字符串。 - - 先创建main.go文件,创建并初始化字符串变量,同时声明main函数: ```go @@ -244,6 +240,7 @@ TEXT ·main(SB), $16-0 CALL runtime·printnl(SB) RET ``` + `TEXT ·main(SB), $16-0`用于定义`main`函数,其中`$16-0`表示`main`函数的帧大小是16个字节(对应string头部结构体的大小,用于给`runtime·printstring`函数传递参数),`0`表示`main`函数没有参数和返回值。`main`函数内部通过调用运行时内部的`runtime·printstring(SB)`函数来打印字符串。然后调用`runtime·printnl`打印换行符号。 Go语言函数在函数调用时,完全通过栈传递调用参数和返回值。先通过MOVQ指令,将helloworld对应的字符串头部结构体的16个字节复制到栈指针SP对应的16字节的空间,然后通过CALL指令调用对应函数。最后使用RET指令表示当前函数返回。 @@ -251,13 +248,13 @@ Go语言函数在函数调用时,完全通过栈传递调用参数和返回值 ## 特殊字符 -Go语言函数或方法符号在编译为目标文件后,目标文件中的每个符号均包含对应包的绝对导入路径。因此目标文件的符号可能非常复杂,比如“path/to/pkg.(*SomeType).SomeMethod”或“go.string."abc"”。目标文件的符号名中不仅仅包含普通的字母,还可能包含诸多特殊字符。而Go语言的汇编器是从plan9移植过来的二把刀,并不能处理这些特殊的字符,导致了用Go汇编语言手工实现Go诸多特性时遇到种种限制。 +Go语言函数或方法符号在编译为目标文件后,目标文件中的每个符号均包含对应包的绝对导入路径。因此目标文件的符号可能非常复杂,比如“path/to/pkg.(*SomeType).SomeMethod”或“go.string."abc"”等名字。目标文件的符号名中不仅仅包含普通的字母,还可能包含点号、星号、小括弧和双引号等诸多特殊字符。而Go语言的汇编器是从plan9移植过来的二把刀,并不能处理这些特殊的字符,导致了用Go汇编语言手工实现Go诸多特性时遇到种种限制。 -Go汇编语言同样遵循Go语言少即是多的哲学,它只保留了最基本的特性:定义变量和全局函数。同时为了简化Go汇编器的词法扫描程序的实现,特别引入了Unicode中的中点`·`和大写的除法`/`,对应的Unicode码点为`U+00B7`和`U+2215`。汇编器编译后,中点`·`会被替换为ASCII中的点“.”,大写的除法会被替换为ASCII码中的除法“/”,比如`math/rand·Int`会被替换为`math/rand.Int`。这样可以将中点和浮点数中的小数点、大写的除法和表达式中的除法符号分开,可以简化汇编程序词法分析部分的实现。 +Go汇编语言同样遵循Go语言少即是多的哲学,它只保留了最基本的特性:定义变量和全局函数。其中在变量和全局函数等名字中引入特殊等分隔符号支持Go语言等包体系。为了简化Go汇编器的词法扫描程序的实现,特别引入了Unicode中的中点`·`和大写的除法`/`,对应的Unicode码点为`U+00B7`和`U+2215`。汇编器编译后,中点`·`会被替换为ASCII中的点“.”,大写的除法会被替换为ASCII码中的除法“/”,比如`math/rand·Int`会被替换为`math/rand.Int`。这样可以将中点和浮点数中的小数点、大写的除法和表达式中的除法符号分开,可以简化汇编程序词法分析部分的实现。 -即使暂时抛开Go汇编语言设计取舍的问题,中点`·`和除法`/`两个字符的如何输入就是一个挑战。这两个字符在 https://golang.org/doc/asm 文档中均有描述,因此直接从该页面复制是最简单可靠的方式。 +即使暂时抛开Go汇编语言设计取舍的问题,在不同的操作系统不同等输入法中如何输入中点`·`和除法`/`两个字符就是一个挑战。这两个字符在 https://golang.org/doc/asm 文档中均有描述,因此直接从该页面复制是最简单可靠的方式。 -如果是macOS系统,则有以下几种方法输入中点`·`:在不开输入法时,可直接用 option+shift+9 输入;如果是自带的简体拼音输入法,输入左上角`~`键对应`·`,如果是自带的Unicode输入法,则可以输入对应的Unicode码点。 +如果是macOS系统,则有以下几种方法输入中点`·`:在不开输入法时,可直接用 option+shift+9 输入;如果是自带的简体拼音输入法,输入左上角`~`键对应`·`,如果是自带的Unicode输入法,则可以输入对应的Unicode码点。其中Unicode输入法可能是最安全可靠等输入方式。 ## 没有分号