编译器移植的难度
‘壹’ 汇编语言编程几乎不能移植,而C/C++等就容易移植 有点搞不明白
汇编语言,和机器语言一样,是直接控制硬件的。
每种CPU,都有自己的机器语言,所以汇编不能移植。
c语言,并不直接控制硬件。
在不同的机器上,有相应的编译软件,可以把C,编译成自己系统的机器语言。
容易移植的关键:C语言是不直接控制硬件的。
‘贰’ 开发一个 C++ 编译器的难度有多大,难点又在哪里
C++的前端是出了名的复杂度和可靠性要求并驾齐驱的软件。
(这两点都比它高一个数量级的大概就只有OS了)
对于这种系统,唯一的办法就是烧钱。
烧钱的作用主要包括:
1.留人;
2.填坑;
3.买买买。
先说留人:复杂度一般是“细节”的代名词。现实中的编译器大多数以递归下降为主,自底向上的归纳推导为辅。这两样在教科书上也就是几页纸的事情。但是现实总是很残酷的,人们总想让语言更加“易用”,这就意味着各种上下文相关的情况都会出现。
对于C++来说,你要判断一个符号是类型或者变量(比如这个符号被用在模板参数中),要看前面的声明/定义。这就是一个上下文相关的推导。然后你就会写大量的if else switch case之类的代码来解决各种各样的可能分支。写它的人当然知道它是做什么的,但是如果这个人离职了,新来一个人,就呆掉了,这写的都是什么煞笔玩意儿。因为它不知道现实中怎样的需求会导致奇形怪状的逻辑。所以人员的稳定,对于这种长周期迭代、逻辑复杂的项目是很重要的。但是人的水平要求高吗?不算高也不算低。总结来说就是:有逻辑,知好歹。技术什么都可以培养,但是态度和基本智商是比较难培养起来的。
至于怎么保证人员稳定?很简单:加薪。
再说填坑:编译器是对正确性要求很高的基础软件。这里的正确性既包括产生的代码的正确性,也包括编译器自身对于各种问题的容忍度和足够丰富的错误提示。容错和错误提示本身也是代码,也有很大的出错几率。所以这些软件,bug少不了。但是作为基础软件,你又不能随便就2+3搞成了2*3,这样还怎么让别人相信爱情。所以要烧很多钱来养一帮debugger。
再说买买买:古人日:我们不用很麻烦很辛苦也可以成佛。既然这么费神我们自己做干什么,不如买别人的吧。于是MS就干脆不自己做了,直接去EDG整了个前端,这样就可以少了不少人年。这就是传统土豪和水果这种新暴发户想的不一样的地方。
传统土豪想的是:我们有这么多钱为什么还要自己解决问题呢?买买买!
水果新贵则是:啊呀,不小心有了这么多钱,我们要不要给自己制造点问题好把这些钱花出去?
‘叁’ 编译器 可移植性问题
你用tc编的程序,在windows下面可以运行,tc把它编译成二进制了
只要是windows系统,都能识别该二进制,换了其他的windows系统的电脑,以都能运行的
也就是说,对于windows系统来说,无论你用什么语言,如pascal,delphi,c++,java,只要你编译后生成了可执行文件
把它放到其他windows系统的电脑上,也都可以运行的
但是,就算是同一台电脑,如果你既安装了windows,又安装了linux
你在windows下编译出来的可执行文件,切换到linux系统下,就不能运行了
当然了,如果放在其他的系统上,如手机的symbian系统上,也是不能运行的
补充回答:
生成的二进制文件的移植性,是由操作系统,如windows,linux保证的
而我们说的c语言的移植性,是指c语言源码能否在其他系统上编译
比如我在windows环境下,写了一段c代码,放到linux下,仍然可以编译,这就说明它的移植性很好
所以,要提供c语言的移植性,必须使用标准的c的代码
如果你调用了windows的api,那么在linux下,是无法编译通过的
‘肆’ 操作系统内核和编译器哪个难度更大
整体而言,是同级别的难,但难点各有侧重。
若论算法,编译器更难,而且难不止一个级别。操作系统的算法难度只能算一般水平。
但是操作系统涉及的东西更多,本身结构更复杂,硬件处理也更加复杂。
‘伍’ 关于代码移植的问题
你可以这么考虑:
VC中的代码是基于WIN的,移植后的代码是基于XX的。
都会有一个封装层来屏蔽硬件的细节。
对于上层应用来讲,会基于一些良好的API来编程。而这些API都会是相似的名字。比如两个平台都会有内存操作的函数,也许都有memcpy这样的关键字。方便使用和记忆。
从这个角度讲,可能不同平台的编译器连接器造成的代码差异要大于硬件细节的差异。
当然了,如果是做内存管理这样需要和硬件细节打交道的模块。这个模块流程,设计上的差异就很明显了。这样的部分,一般都称为移植层。这个层变动是最大的。这个层也就是前面说的“封装层”。
‘陆’ 为什么高级语言程序比汇编语言程序更容易从一种计算机移植到另一种计算机上
高级语言使用了编译器的不可移植性来实现了语言的可移植性,意思就是他们公司为每个操作系统写了个编译器,编译过后形成该系统中可以运行的东西,当然可以运行了。而制作汇编那公司如果没有别的编译器来适应不同的操作系统,就不能编译。
‘柒’ C语言编译器移植问题
楼主既要使用C语言编译器,又想使用C++编译器的话,编码风格要使用标准C语言的风格,这样C++同时可以兼容。
VC6编译报错可能是如下原因:
1、局部变量的定义和初始化必须在函数的最开始,不能放在函数的中间部分
2、scanf_s函数的使用,scanf_s并不是标准的库函数,有些编译器并没有该函数,推荐使用scanf函数,虽然不太安全
VS2013运行错误可能是如下原因:
1、很多带“_s”后缀的函数是为了让原版函数更安全,传入一个和参数有关的大小值,避免引用到不存在的元素,有时hacker可以利用原版的不安全性黑掉系统。比如:char d[20];写成scanf_s("%s",d,20);才是正确的,有这个参数20使准确性提高。既然使用了scanf_s函数,就不能单纯的写scanf_s(" %s [%d][%d]", s, &m, &n);,就需要对%s制定可以输入的最大字符才行
intm,n;//局部变量放在函数的最开始
chars[6];
intsize=4;
void*p;
int*q;
inti,j;
printf("请定义一个二维数组,格式如下:int[3][4] ");
printf("数组类型只限于int,char,float,int*,char* ");
printf("请只在声明数据类型和数据之间输入空格! ");
printf("本程序容错性很差,请按照要求谨慎操作! ");
scanf_s("%s[%d][%d]",s,5,&m,&n);//s,5,指明s最多接收5个字符
p=malloc(size*m*n);
q=(int*)p;
memset(p,1,size*m*n);
‘捌’ 如何给CPU移植编译器
如果连GCC都不支持你的CPU的话,我劝你不要在上面花功夫了,不是一般人做得出来的,也不是一天两天做得出来的,相当于你要从头实现一次GCC中的汇编处理和连接处理,而首先要了解相关CPU的指令集,机器码,然后再谈别的。
所谓交叉编译环境都是指在GCC所支持的CPU的情况下,才能建立。
一个编译器有编译程序的时候,大概要经历预处理,语法,词法分析,优化,产生中间代码,编译,连接等过程,如果是一套GCC都不支持的CPU,预处理,语法,词法分析,优化过程可以跟与它差不多的CPU共享同样的过程,但产生中间代码,编译连接与具体的CPU有很大的相关性
我们现在举一个例子来说明:比如我们建立一个支持ARM的交叉编译环境
这个例子你与所说的要求还有一定区别(因为GCC支持ARM),不过通过这个例子可以引申出你需要做的事情,第一件要做的事情用在PC机上的GCC来编译一套用于ARM的编译工具,就是所谓的bilutils工具,包括用于ARM芯片的as,ld等程序,第二件事情就是用第一步中所产生的那套工具来编译GCC(用于ARM的),第三件事是用第二步所产生的工具来编译GLIBC库,当然,你也许还需要它对C++的支持,那么就得再编译对C++的支持,比如G++,STL库等
而LZ现在要做的工作除了上述要求之外,还有最重要的工作要做,就是在GCC中加入产生as,ld等工具的代码,很显然,这个工作量巨大,而且很难,比如你写一个最简单的C文件,里面仅声明一个整型变量,此时你自巳的编译器在前期处理阶段与x86没什么区别,可以照抄,那么如何让它变成机器码呢?这就是你需要做的工作,我没有做过类似的工作,在这里仅是建议,你需要去深入理解GCC源码,然后再加入你自己的实现,我想你加入的部分比起整个GCC来说,应该是非常少的,因为你可以共享很多与体系无法的代码。
‘玖’ 把应用程序移植到PowerLinux容易吗
:难易取决于应用程序的特点,但通常来说移植很简单容易。移植后,真正的工作可能是优化那些性能敏感的程序,特别包含了编译器和不可移植,平台依赖的代码,这两种特性增加移植时间。
看更特殊的,作为答案,我们可以把应用程序分组和深入描述它们移植的可能性,如下:
· Java和开源结构的程序可以“直接运行”在PowerLinux上。
o 不论用Java还是脚本语言比如PHP或者Perl写的程序可以“直接运行“在PowerLinux上。Java调试指南已经发布用于给这些程序有效地运行在Power系统上提供帮助。
o RedHat和SUSE为Power发布的版本中最流行的开源应用程序如Apache,Tomcat,MySQL,Squid,Postfix,等,可“直接运行”于PowerLinux。
· 用GNU工具编译的客户程序(C/C++等)通常需要在PowerLinux服务器上简单地从新编译一下。如果这些程序避免含有特殊代码比如汇编语言,那么它们同样可以“直接运行”
o 我们最新的Eclipse基于PowerLinux 软件开发工具包 (SDK) 提供给X86 Linux开发者一个非常熟悉的环境。很多用户报告重新编译非常快,也就几分钟。源于IBM花费数年来研发开发工具。
o SDK也提供移植工具(比如IBM的Chiphopper program)来帮助移植过程和性能调优工具用于移植后工作。
o 另外,SDK也提供最新和最快的GNU工具和库文件套装,称为PowerLinux高级工具链
o Porting to Linux on Power wiki网页是开始这个过程的最佳地方。
· IBM SWG可用于PowerLinux的应用程序每月都在增加。这些程序可以用于多平台和操作系统,包括PowerLinux.
o SWG维护下面的网站,以提供SWG平台支持的产品的最新列表。比如如何搜索Power上的RHEL或者SUSE版本和在软件产品兼容报告网站上生成能支持的应用程序的PDF列表
o 使用软件产品兼容报告的更多细节请参阅PowerLinux定位程序 wiki网页。
· PowerLinux第三方ISV程序集每月也在增加,主要围绕跟大数据量程序,工业程序和开源结构有关的ISV。
o 这些程序在合作伙伴全球解决方案目录链接中维护更新。更多使用全球解决方案目录的细节可为PowerLinux定位程序 wiki网页找到。
o 如果应用程序不可用于PowerLinux,IBM有一些程序帮助ISV迁移他们的程序,包括:
§ 有销售前景的快速移植
§ Chiphopper提供免费科技协助和X86 Linux到PowerLinux的移植工具
§ 为远程访问PowerLinux服务器的虚拟租赁程序( Virtual Loaner Program),移植工具和技术支持资源
§ IBM为本地,在线访问上述资源的创新中心
‘拾’ 既然大部分语言都具有移植性,为什么现在的应用程序依然有很大的平台局限性
比较上层的语言(通常是脚本语言)不太受系统环境的影响,这也就是为什么同一款浏览器插件可以在不同系统的浏览器上运行的原因。
相反,比较底层的语言(C,汇编语言等)受制于硬件接口,如果你认真学习过硬件方面的知识的话你就会知道不同的系统对同一个硬件IO的命令是不一样的,而这个不一样不只是二进制机器语言上的不同,而是源代码就有很大的区别。例如UNIX环境下网络编程使用套接字通常调用<sys/socket.h>下的函数,而windows环境下根本没有这个头文件。 如果一款底层编写的程序不需要任何处理就可以移植到另一个平台上,那么说明它几乎没有怎么使用高级硬件IO,也就是说它基本没什么用。。。。