【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

之前写过一篇ucc的文章,也就是这一篇。这篇文章对ucc的流程说了挺多,但是怎么把ucc移植到新的cpu上面,却没有说很多,后来自己又看了一下代码,发现还是有不少新的收获。

文章目录

  • 1、emit.c
  • 2、x86linux.c & x86win32.c
  • 3、x86.c
  • 4、x86linux.tpl & x86linux.tpl
  • 5、opcode.h
  • 6、reg.c
  • 7、其他体系应该怎么移植
  • 8、github链接
  • 9、编译和链接

1、emit.c

emit.c文件是真正的后端入口,所有的汇编文件的整理、组织部分都是这里完成的。当然这部分只是框架的内容,告诉我们一个大概,全局变量怎么放,字符串怎么放、函数怎么放等等。涉及到具体的内容还要依赖于具体的cpu体系文件。

2、x86linux.c & x86win32.c

因为ucc只是涉及到了x86的部分,所以这里只谈x86。当然,同时因为在linux和windows平台上面,两者的汇编文件格式有所差别,所以这里有两个翻译文件。上面变量怎么放、字符串怎么放,emit.c就会调用这两个文件里面的对应函数。

3、x86.c

如果说是普通的格式,那么x86linux.c & x86win32.c都可以完成,但是如果是具体函数的翻译,那么只能在x86.c里面完成了。当然,涉及到具体的PutASMCode指令部分,还是需要调用x86linux.c & x86win32.c这两个文件的。因为编译的过程比较复杂,特别是对于堆栈的计算、函数的压栈和出栈部分,这部分需要仔细研究和推敲。

4、x86linux.tpl & x86linux.tpl

这是两个翻译模块,分别被包含在上面x86linux.c & x86win32.c文件中。分离出来,只是为了让结构更清晰一点。这部分和编译器生成的中间代码,几乎是一一对应的。

5、opcode.h

这部分是比较容易忽视的部分,其实这部分最重要。因为其实它就包含在x86.c文件。本身描述的也是中间代码格式,后端翻译的本质就是将中间代码,按照模板翻译成汇编,就是这么简单。

6、reg.c

寄存器分配是几乎所有体系结构都会遇到的问题,但是ucc处理的方法比较简单,就是尽量把临时变量保存到寄存器,实在保存不了,只好压栈。这样效率不一定高,但是不会出错。

7、其他体系应该怎么移植

如果要移植到其他的汇编语言,比如mips,那么也需要成立这么几个文件,即mips.c、mips_linux.c、mips_linux.tpl文件,同时mips_linux.tpl包含在mips_linux.c中,opcode.h包含在mips.c中,mips.c调用mips_linux.c的PutASMCode函数,按照中间代码的类型生成每一个emit函数,比如EmitMove。mips_linux.tpl需要像x86linux.tpl一样,对opcode.h中的每一个中间格式进行翻译。有兴趣的同学可以试一试。

8、github链接

ucc本身还是非常不错的代码,常看常新,github上也有对应的链接。代码内容也非常适合用来学习和研究。

9、编译和链接

ucc的本身完整编译依赖于gcc生成预处理文件、asm文件生成obj文件、obj文件生成exe文件,这就是ucc的高明之处。因为ucc自己只实现了ucl,也就是c文件到asm文件的这部分,而这部分的工作确是非常有意义的。一方面对于学生来说,可以知道编译原理的基本思路,另外一方面,对于某些行业、比如安全关键行业,完全可以做一些私人化的定制,这是很有意义的。我们可以看一下,完整ucc运行时,依赖哪些命令,

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "ucc.h"#define _P_WAIT 0
#define UCCDIR "/home/iron/bin/"/**ucc -E -v hello.c -I../ -DREAL=double -o hello.iiFor $1/$2/$3 ,see BuildCommand() for detail.$1       -I../ -DREAL=double,   command-line options$2      hello.c,        input file$3        hello.ii,       output file
*/
char *CPPProg[] =
{ "/usr/bin/gcc", "-m32", "-U__GNUC__", "-D_POSIX_SOURCE", "-D__STRICT_ANSI__","-Dunix", "-Di386", "-Dlinux", "-D__unix__", "-D__i386__", "-D__linux__", "-D__signed__=signed", "-D_UCC", "-I" UCCDIR "include", "$1", "-E", "$2", "-o", "$3", 0
};/**ucc -S -v hello.c --dump-ast -o hello.asm------->/home/iron/bin/ucl -o hello.asm --dump-ast hello.i$1   --dump-ast, some command-line options$2 hello.i,    input file$3    hello.asm,  output file
*/
char *CCProg[] =
{UCCDIR "ucl", "-o", "$3", "$1", "$2", 0
};char *ASProg[] =
{ "/usr/bin/gcc", "-m32", "-c", "-o", "$3", "$1", "$2", 0
};char *LDProg[] =
{"/usr/bin/gcc", "-m32", "-o", "$3", "$1", "$2", UCCDIR "assert.o", "-lc", "-lm", 0
};char *ExtNames[] = { ".c", ".i", ".s", ".o", ".a;.so", 0 };int Execute(char **cmd)
{int pid, n, status;pid = fork();if (pid == -1){fprintf(stderr, "no more processes\n");return 100;}else if (pid == 0){execv(cmd[0], cmd);perror(cmd[0]);fflush(stdout);exit(100);}/**wait():  on success, returns the process ID of the terminated child; onerror, -1 is returned.*/while ((n = wait(&status)) != pid && n != -1);if (n == -1)status = -1;if (status & 0xff){fprintf(stderr, "fatal error in %s\n", cmd[0]);status |= 0x100;}return (status >> 8) & 0xff;
}void SetupToolChain(void)
{}

ucc编译器(x86移植)相关推荐

  1. ucc编译器(入门)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 要说开源编译器,一般大家想到的都是gcc.但是现在gcc的代码量太大了,不太适合学习.代码量比较 ...

  2. ucc编译器(优化)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 编译器优化几乎是现代编译器最重要的工作.一般编译器的优化有这么几层,a,中间代码生成前的优化,比 ...

  3. ucc编译器(中间代码生成)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 所谓中间代码生成,就是生成一种和具体汇编语言无关的中间代码.生成中间代码有很多的好处,一方面它可 ...

  4. ucc编译器(语法解析)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 做完词法分析,后面紧接着就是语法分析.对于一个编程语言而言,语法解析才是语言和语言之间最大的区别 ...

  5. ucc编译器(词法分析)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 学过编译器的同学都知道,词法分析是编译器里面最基础的一条.之前,在学校读书的时候,老师也会告诉我 ...

  6. ucc编译器(语义分析)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 符合语法的代码,不一定符合语义.这句话听上去很拗口,我们不妨举个例子,假设我们定义了一个变量in ...

  7. linux游戏移植,英特尔移植AMD编译器代码可将Linux游戏性能提高10%

    Linux游戏可能不如Windows游戏流行,但它是一个增长中的细分市场.在支持和性能方面,它也在改善.与后者有关,英特尔开放源代码3D驱动程序团队的成员Jason Ekstrand在将AMD编译器代 ...

  8. C/C++编译器gcc的windows版本MinGW-w64安装教程

    一.什么是 MinGW-w64 ? MinGW 的全称是:Minimalist GNU on Windows .它实际上是将经典的开源 C语言 编译器 GCC 移植到了 Windows 平台下,并且包 ...

  9. C编译器剖析_5.3.2 中间代码生成及优化_switch语句的翻译

    5.3.2.Switch语句的翻译 在这一小节中,我们来讨论一下switch语句的翻译,switch语句的产生式如下所示. SwitchStatement: switch( expr ) statem ...

最新文章

  1. 如何快速地掌握PowerShell?
  2. java 微商城开发_Java网上商城系统可以开微信商城吗
  3. myemployees库的四张表介绍
  4. mysql 查询时间转换_数据库查询时日期的转换
  5. 计算机考试上机安排,全国计算机等级考试模拟上机安排(最终版).doc
  6. 时间格式化及操作(moment.js篇)
  7. 下一版本的Android OS ——Jelly Bean
  8. 图像处理_如何保存浮点型数值的图像? (C++ / OpenCV)
  9. C语言求组合数取模,C 习题1.pdf
  10. 【hdu2588】求[1-n]中和n的gcd大于m的数的个数(求欧拉函数值)
  11. C1见习工程师(一)
  12. android关联发送程序,Android Handler机制之Message的发送与取出
  13. jenkins插件下载加速
  14. Asp.net web服务处理程序(第六篇)
  15. 一、Scrapy爬虫概述
  16. js 深浅拷贝的整理
  17. html视频倍速播放,如何让网页视频倍速播放
  18. 【U盘主控芯片的优缺点】
  19. 直播疑难杂症排查(7)— 黑屏、花屏、闪屏问题
  20. C# MQTT 消息订阅

热门文章

  1. 《精通Spring 4.x 企业应用开发实战》读书笔记
  2. 使用脚本将域账号添加到客户机的本地管理员组
  3. 解决AutoCAD acmgd.dll ARX命令中发现异常
  4. 类里面没有参缺省构造函数 的带来的问题
  5. 20、在Linux中实现类似windows中获取配置文件的函数GetProfileString
  6. C# 设置DateTime类型的变量值等于Null
  7. 数据库sql server 2008安装。
  8. 用户名错误则一直登录
  9. 2018-2019-2 《网络对抗技术》Kali安装 Week1 20165212
  10. 2018.7.28 二叉树的遍历规则(前序遍历、后序遍历、中序遍历)