erlangsir 发表于 2010-08-22 23:12

本帖最后由 erlangsir 于 2010-08-22 23:15 编辑


void test()
{
    int a;
    int b;
    int c;

    a = b + c;
}
UNIX下的C语言编译器,一般都提供了-S选项,用于观察汇编输出,sc似乎没有提供这个选项,直接生成了elf可执行文件;那么,以上面的代码为例,该如何观察sc编译后的汇编输出(ARM或者80386)?

TOK_Wang 发表于 2010-08-23 10:59

UNIX下的C语言编译器,一般都提供了-S选项,用于观察汇编输出,sc似乎没有提供这个选项,直接生成了elf可执 ...
erlangsir 发表于 2010-08-22 23:12 http://linux.chinaunix.net/bbs/images/common/back.gif

sc 中有个“-sasm”选项输出汇编代码。可以试一下。

TOK_Wang 发表于 2010-08-23 11:03

文本文件test内容为:使用sc -c -sasm test命令编译后,得到文件test.sasm,其内容为:

为什么a、b、c三 ...
erlangsir 发表于 2010-08-22 22:57 http://linux.chinaunix.net/bbs/images/common/back.gif

汇编生成这块刚刚开始做,这只是一个demo。:)

steven_known 发表于 2010-08-25 09:54

回复 13# TOK_Wang
如果我没理解错的话, 目前sc没有生成汇编文件就能够得到obj目标文件。

也就是说 sc 在最后的代码生成阶段直接从最低阶的IR生成对应的二进制机器码,并组装成obj,对吗?

TOK_Wang 发表于 2010-08-25 10:47

回复 14# steven_known

怎么可能这样设计啊,析码的架构把机器特性完全隔离了,其中有一个“back-para”,出于兼容性考虑例如目标机的改变不会牵动全身。你说的IR在“mid-para”部分,这些是完全可重用的。

steven_known 发表于 2010-08-25 12:15

回复 15# TOK_Wang

哦,我想你误解我的意思了,

IR可以分为多个层次,
High Level IR:带有高级语言特征
Mid Level IR: 用来做Scalar optimization的
Low Level IR: 用来进行代码生成和平台相关优化的

我指的当然是Low Level IR。而之前你说生成ASM File部分正在进行中,却能已经能生成ELF可执行文件。
但在实际开发中通常要先把代码生成部分做正确,才考虑继续向下进行,而从上面 erlangsir 提供的例子来看,代码生成和寄存器分配似乎有问题。

所以我猜测你们在没生成ASM File的情况下,从Low Level IR生成ELF,或者说,目前仅仅是演示一下sc的各模块的效果。

TOK_Wang 发表于 2010-08-25 13:03

本帖最后由 TOK_Wang 于 2010-08-25 13:22 编辑

回复 16# steven_known

是这样的,现在刚刚完成了基础架构,还有很多细节需要做。至于你指出的“...在实际开发中通常要先把代码生成部分做正确,才考虑继续向下进行...”这种开发模式各人认为并不适合这个项目。现在的可以尽快得出一个原型尽早发现架构层面的设计问题,毕竟我们是第一次独立开发一个完整的编译器,这完全摸着石头过河的,也是出于这个原因可以这么说SC完全不同于市面上其它同类产品。相关细节可以看一下:http://www.tok.cc/wiki/doku.php?id=projects:compiler:smart_compiler

kallytin 发表于 2010-09-03 03:50

回复 1# TOK_Wang

TOK_Wang,

请教一下,在你的编译器里有关C的预处理器是如何实现的?大致的思路就行,谢谢。

TOK_Wang 发表于 2010-09-03 14:37

回复 18# kallytin

实现就是用若干字符串处理接口+一个词法分析器。
具体就是:
“预编译指令”作为一个独立阶段处理,基于标准中的定义搜索代码,某些指令会产生一个类似于语法解析的过程(#ifdef #ifndef 等)。
“宏”替换,需要注意回路。
“常数表达式”,用求值器。

宏的回路,例如:

#define C(x) A ffff x F A F ff C(x) A B(x)
#define A A FF A
#define F A ffff
#define B(x) C(x) B(x) x
C(gtkings)

这种东西标准中没有定义,只是多数编译器默认的处理方式。

kallytin 发表于 2010-09-03 15:27

回复kallytin

实现就是用若干字符串处理接口+一个词法分析器。
具体就是:
“预编译指令”作为一个 ...
TOK_Wang 发表于 2010-09-03 14:37 http://linux.chinaunix.net/bbs/images/common/back.gif

谢谢你的回复。

我有2点疑问:

1、像 "#define A B" 这类的宏替换你是在什么阶段实现的?怎样实现的?

2、像 "#ifdef #end" 你是怎样实现的?

我的理解:

对于1,我最初的理解是单独在预处理阶段实现,即在“词法分析”阶段之前。这里解释一下,我的词法分析阶段和语法分析阶段都是不包括预处理的内容的。因此对于预处理器,我是单独包括“包含文件合并”、“预处理器的词法分析”、“预处理器的语法分析”等。后来,慢慢发觉这样的做法似乎不太行得通,原因如下:

1)对于宏替换,如果有 N 条宏替换语句,则需要 N 遍扫描文件,以进行替换。

2)另外,对于 “#define A” 这类语句,是需要使用符号表进行记录的(记录A已定义),因此预处理阶段也不能独立于其他阶段。

对于2,个人感觉也是应该在“预处理阶段”实现,但后来的看法也变了,原因如下:

例如: #ifndef DEBUG
          #define A 1
       #end

这里也是先要查找符号表以确定 DEBUG 是否已定义,再决定是否需要宏替换,而且如果需要宏替换的话,个人感觉是需要借助符号表实现的,而不是在文件上将 A 替换成 1。

综上所述,我感觉预处理器不应该单独处理,而应该分拆在各个阶段进行处理(但这样会产生一些额外的问题,例如上面例子里的 A ,如果在符号表中它应该是一个符号,但类型不好确定(更直接的例子是 #define A B,A 和 B 的类型如何确定?)。

如果单独处理预处理器,个人感觉“预处理阶段”也应独立包含“预处理器的词法分析”、“预处理器的语法分析”等,最后将符号表共享至下一阶段。

上面只是我个人的一些看法,还没有去验证,不知道对不对(要改之前的逻辑,还是比较烦的,因此想先确定一下)?
页: 1 [2] 3
查看完整版本: Semo Compiler(析码)编译框架 0.2.0 代码,ARM、ELF、SSA等