大家好,如果您还对fc网站源码分享不太了解,没有关系,今天就由本站为大家分享fc网站源码分享的知识,包括fc游戏 源码的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!
作者|qcrao
责编|屠敏
出品|CSDN博客
刚开始写这篇文章的时候,目标非常大,想要探索Go程序的一生:编码、编译、汇编、链接、运行、退出。它的每一步具体如何进行,力图弄清Go程序的这一生。
在这个过程中,我又复习了一遍《程序员的自我修养》。这是一本讲编译、链接的书,非常详细,值得一看!数年前,我第一次看到这本书的书名,就非常喜欢。因为它模仿了周星驰喜剧之王里出现的一本书——《演员的自我修养》。心向往之!
在开始本文之前,先推荐一位头条大佬的博客——《面向信仰编程》,他的Go编译系列文章,非常有深度,直接深入编译器源代码,我是看了很多遍了。博客链接可以从参考资料里获取。
理想很大,实现的难度也是非常大。为了避免砸了“深度解密”这个牌子,这次起了个更温和的名字。
下面是文章的目录:
引入
我们从一个HelloWorld的例子开始:
packagemainimport”fmt”func 当我用我那价值1800元的cherry键盘潇洒地敲完上面的helloworld代码时,保存在硬盘上的hello.go文件就是一个字节序列了,每个字节代表一个字符。 用vim打开hello.go文件,在命令行模式下,输入命令: :%!xxd
就能在vim里以十六进制查看文件内容: 最左边的一列代表地址值,中间一列代表文本对应的ASCII字符,最右边的列就是我们的代码。再在终端里执行manascii: 和ASCII字符表一对比,就能发现,中间的列和最右边的列是一一对应的。也就是说,刚刚写完的hello.go文件都是由ASCII字符表示的,它被称为文本文件,其他文件被称为二进制文件。 当然,更深入地看,计算机中的所有数据,像磁盘文件、网络中的数据其实都是一串比特位组成,取决于如何看待它。在不同的情景下,一个相同的字节序列可能表示成一个整数、浮点数、字符串或者是机器指令。 而像hello.go这个文件,8个bit,也就是一个字节看成一个单位(假定源程序的字符都是ASCII码),最终解释成人类能读懂的Go源码。 Go程序并不能直接运行,每条Go语句必须转化为一系列的低级机器语言指令,将这些指令打包到一起,并以二进制磁盘文件的形式存储起来,也就是可执行目标文件。 从源文件到可执行目标文件的转化过程: 完成以上各个阶段的就是Go编译系统。你肯定知道大名鼎鼎的GCC(GNUCompileCollection),中文名为GNU编译器套装,它支持像C,C++,Java,Python,Objective-C,Ada,Fortran,Pascal,能够为很多不同的机器生成机器码。 可执行目标文件可以直接在机器上执行。一般而言,先执行一些初始化的工作;找到main函数的入口,执行用户写的代码;执行完成后,main函数退出;再执行一些收尾的工作,整个过程完毕。 在接下来的文章里,我们将探索编译和运行的过程。 编译链接概述 Go源码里的编译器源码位于src/cmd/compile路径下,链接器源码位于src/cmd/link路径下。 我比较喜欢用IDE(集成开发环境)来写代码,Go源码用的Goland,有时候直接点击IDE菜单栏里的“运行”按钮,程序就跑起来了。这实际上隐含了编译和链接的过程,我们通常将编译和链接合并到一起的过程称为构建(Build)。 编译过程就是对源文件进行词法分析、语法分析、语义分析、优化,最后生成汇编代码文件,以.s作为文件后缀。 之后,汇编器会将汇编代码转变成机器可以执行的指令。由于每一条汇编语句几乎都与一条机器指令相对应,所以只是一个简单的一一对应,比较简单,没有语法、语义分析,也没有优化这些步骤。 编译器是将高级语言翻译成机器语言的一个工具,编译过程一般分为6步:扫描、语法分析、语义分析、源代码优化、代码生成、目标代码优化。下图来自《程序员的自我修养》: 词法分析 通过前面的例子,我们知道,Go程序文件在机器看来不过是一堆二进制位。我们能读懂,是因为Goland按照ASCII码(实际上是UTF-8)把这堆二进制位进行了编码。例如,把8个bit位分成一组,对应一个字符,通过对照ASCII码表就可以查出来。 当把所有的二进制位都对应成了ASCII码字符后,我们就能看到有意义的字符串。它可能是关键字,例如:package;可能是字符串,例如:“HelloWorld”。 词法分析其实干的就是这个。输入是原始的Go程序文件,在词法分析器看来,就是一堆二进制位,根本不知道是什么东西,经过它的分析后,变成有意义的记号。简单来说,词法分析是计算机科学中将字符序列转换为标记(token)序列的过程。 我们来看一下维基百科上给出的定义: 词法分析(lexicalanalysis)是计算机科学中将字符序列转换为标记(token)序列的过程。进行词法分析的程序或者函数叫作词法分析器(lexicalanalyzer,简称lexer),也叫扫描器(scanner)。词法分析器一般以函数的形式存在,供语法分析器调用。 .go文件被输入到扫描器(Scanner),它使用一种类似于有限状态机的算法,将源代码的字符系列分割成一系列的记号(Token)。 记号一般分为这几类:关键字、标识符、字面量(包含数字、字符串)、特殊符号(如加号、等号)。 例如,对于如下的代码: slice[i]=i*(2+6)
总共包含16个非空字符,经过扫描后: 记号类型slice标识符[左方括号i标识符]右方括号=赋值i标识符*乘号(左圆括号2数字+加号6数字)右圆括号 上面的例子源自《程序员的自我修养》,主要讲解编译、链接相关的内容,很精彩,推荐研读。 Go语言(本文的Go版本是1.9.2)扫描器支持的Token在源码中的路径: src/cmd/compile/internal/syntax/token.go
感受一下: vartokstrings=[…]string{//sourcecontrol_EOF:”EOF”,//namesandliterals_Name:”name”,_Literal:”literal”,//operatorsandoperations_Operator:”op”,_AssignOp:”op=”,_IncOp:”opop”,_Assign:”=”,_Define:”:=”,_Arrow:”<-“,_Star:”*”,//delimitors_Lparen:”(“,_Lbrack:”[“,_Lbrace:”{“,_Rparen:”)”,_Rbrack:”]”,_Rbrace:”}”,_Comma:”,”,_Semi:”;”,_Colon:”:”,_Dot:”.”,_DotDotDot:”…”,//keywords_Break:”break”,_Case:”case”,_Chan:”chan”,_Const:”const”,_Continue:”continue”,_Default:”default”,_Defer:”defer”,_Else:”else”,_Fallthrough:”fallthrough”,_For:”for”,_Func:”func”,_Go:”go”,_Goto:”goto”,_If:”if”,_Import:”import”,_Interface:”interface”,_Map:”map”,_Package:”package”,_Range:”range”,_Return:”return”,_Select:”select”,_Struct:”struct”,_Switch:”switch”,_Type:”type”,_Var:”var”,}
还是比较熟悉的,包括名称和字面量、操作符、分隔符和关键字。 而扫描器的路径是: src/cmd/compile/internal/syntax/scanner.go
其中最关键的函数就是next函数,它不断地读取下一个字符(不是下一个字节,因为Go语言支持Unicode编码,并不是像我们前面举得ASCII码的例子,一个字符只有一个字节),直到这些字符可以构成一个Token。 func(s*scanner) 【Gopackage的探索】https://mp.weixin.qq.com/s/OizVLXfZ6EC1jI-NL7HqeA 【Go官方关于Go项目的组织结构】https://golang.org/doc/code.html 【Gomodules】https://www.melvinvivas.com/go-version-1-11-modules/ 【GolangInstallation,Setup,GOPATH,andGoWorkspace】https://www.callicoder.com/golang-installation-setup-gopath-workspace/ 【编译、链接过程链接】https://mikespook.com/2013/11/%E7%BF%BB%E8%AF%91-go-build-%E5%91%BD%E4%BB%A4%E6%98%AF%E5%A6%82%E4%BD%95%E5%B7%A5%E4%BD%9C%E7%9A%84%EF%BC%9F/ 【1.5编译器由go语言完成】https://www.infoq.cn/article/2015/08/go-1-5 【Go编译过程系列文章】https://www.ctolib.com/topics-3724.html 【曹大gobootstrap】https://github.com/cch123/golang-notes/blob/master/bootstrap.md 【golang启动流程】https://blog.iceinto.com/posts/go/start/ 【探索golang程序启动过程】http://cbsheng.github.io/posts/%E6%8E%A2%E7%B4%A2golang%E7%A8%8B%E5%BA%8F%E5%90%AF%E5%8A%A8%E8%BF%87%E7%A8%8B/ 【探索goroutine的创建】http://cbsheng.github.io/posts/%E6%8E%A2%E7%B4%A2goroutine%E7%9A%84%E5%88%9B%E5%BB%BA/ 版权声明:本文为CSDN博主「qcrao」的原创文章。 【END】 1024程序员节如期而至,CSDNBlink小姐姐的关爱来了! 扫描领取小姐姐的专属福利! 程序员邂逅鼓励师的正确姿势!扫描前往福利现场>> 好了,本文到此结束,如果可以帮助到大家,还望关注本站哦!
