» 您尚未登录:请 登录 | 注册 | 标签 | 帮助 | 小黑屋 |


发新话题
打印

[电脑] 外行问一个各种编程软件的问题

1,不同编程软件理论上是不是可以编出同一种功能的软件?比如basic,c++都能写出office??谢谢。
可以
编程语言是相对于编译器来说的,只要编译器能解析编译,你就是用天顶星语言都行。编译器会最终生成2进制可执行代码,由于该可执行程序是在操作系统下运行的,其中包含了大量针对目标OS的section信息,所以它是OS依赖的。它们通常不直接操作硬件(除非是驱动程序),而是直接通过各种封装好的库函数来使用OS提供的系统调用

有一种程序是完全不依赖OS而是直接依赖硬件平台的,比如说bootloader,比如说grub4dos,比如说windows软激活程序,它并不是在OS下运行的,而是直接操作硬件,以及使用bios提供的软中断资源。这类程序在编写时不能调用任何动态库,哪怕一个printf也要自己直接操作硬件寄存器去实现,我们称之为裸板程序。编译时只要在最后生成的可执行程序上多加一道工序(去掉OS依赖的section信息,转换成纯bin文件)即可


2,编写mac系统的软件可以在windows环境下用微软出编程软件编出来么??还是必须是mac系统自己的编程软件?
不清楚微软有没有出过针对mac的交叉编译器,如果有,当然可以
至于为什么,从上面第一点相信你已经能得出答案,不多解释


TOP

关于交叉编译器,欲知详细请猛击下面的网站
http://www.codesourcery.com/



TOP

其实其他平台的引导也是很容易的,只是x86有bios存在变得异常统一

就我自己来说,在手册相关硬件的章节看明白后写一个能引导kernel的bootloader大致在几百行代码左右(99%以上代码是C),真正需要初始化的硬件并不多(时钟、内存、设置中断向量表和中断处理等),主要精力反而在如何将一个几兆大小的kernel镜像弄到内存里。比较简单的是直接从flash或硬盘中读取到内存,复杂的有通过网络下载或传输到内存,那么一个走UDP的网络协议栈大概也是几百行代码,网卡裸板操作的封装也要几百行这样

如果要功能全面的话就移植u-boot过来,代码量看u-boot对该平台支持度而定,大概需要添加和修改千余行代码这样

当然,这只是引导kernel,kernel要在目标平台上运行是肯定要经过移植的,主要工作量其实就在这里,除了添加一些必要的板级启动静态信息外,几乎可以肯定要自己添加许多外设的驱动程序,因为是基于kernel的驱动框架,所以代码量比uboot这种裸板的硬件操作复杂得多


TOP

我发觉我说话越来越没重点了 我来总结下上面说的:启动kernel的过程很容易,工作量的大头是kernel的移植,在熟练kernel的移植后,android的移植也就不难了

还有一些像数码相框之类的项目,则根本不用跑kernel,如此简单的应用可以直接用裸板程序从头到尾实现

TOP

只要在汇编里设好栈指针就可以跳到C里去了,有一些只能用cpu特定的汇编指令操作的寄存器也可以用内嵌汇编

这里面唯一一个算的上难点的地方是运行地址和链接地址的区别,必须清楚C语言中哪些语法特性是用链接地址实现的,比如函数指针。如果不能确定就用反汇编观察

之所以要区分运行地址和链接地址是因为有些平台的启动过程中,第一条指令在内部sram中执行,之后在初始化了内存后才把自身copy到内存中并跳过去的,由于绝大部分代码是在内存中运行,所以在代码编译链接的时候指定的地址是内存地址而非sram地址,这样在sram中运行时实际运行地址和链接地址是不一致的,在这种状态下是不能使用依赖链接地址的指令和语法特性的

TOP

我感觉跑OS主要是为了简化应用程序的开发,如果是实现单一功能明显自己直接上更快更高效啊,单一功能就可以自己针对性地对内存优化对电源管理优化,没有进程调度那么实时性更能得到保证,网络栈usb协议栈么现成的一大堆

没有MMU的话只能跑uclinux之类,但是没有MMU就意味着多任务很难实现,对应用层要求过高,我感觉没太大意思,现在带MMU的SoC价格也不贵,不至于价格敏感到这地步。我感觉更多的是为了招标时吹水,当然还有种可能是有商业的现成的uclinux可用,为了省事

TOP

C语言中函数指针的实现、全局变量的访问(我记得是所有非text段的访问,连rodata段也是如此)都是依赖链接地址的,在链接的时候,链接器通过参数给定的链接首地址加上计算出的偏移量,然后把这个地址直接写死在了bin文件里。程序在执行的时候是从相应的text段中将地址取出来使用的,而不是通过pc指针来计算便宜的

每次有人遇到地址相关导致的错误我都会耐心讲一遍,还用反汇编代码说明,但是我感觉好像从来没人听明白过

TOP

交叉编译是针对目标OS和硬件平台的,交叉编译器需要提供对应OS的动态库。只要是编译的程序运行环境和当前编译器所处的运行环境不同,就需要交叉编译

如果是编译裸板程序,则可忽略OS,只对应硬件平台,并且不使用动态库即可。在gcc4.4.1以后,裸板程序在编译时需要添加-ffreeestanding选项,但是使用的交叉编译器是完全一样的。裸板程序和基于OS的应用程序的区别实际上主要是在编码上,而编译过程只需要添加一步生成bin文件的步骤即可。就交叉编译的角度来说,其实没有区别,交叉编译器提供的目标OS的动态库不使用就是了

内嵌汇编的处理完全是看编译器的,和语言无关。同样的硬件平台,gnu使用AT&T规范是必然,因为要对应多种cpu,不可能在arm平台下遵循arm规范,在intel平台下遵循intel规范,那就乱套了。AT&T规范相当严谨,考虑到了几乎所有可能出现的因为编译器优化而导致的错误

我从来没有过出于性能优化的考虑去使用内嵌汇编,性能优化只要用inline关键字修饰循环调用的函数就行了。内嵌汇编在大部分情况下反而是性能劣化,如果要用汇编做大量工作,不如在高级语言中直接以函数的形式调用汇编。所以我想象不出应用层调汇编是为了干啥

TOP

引用:
原帖由 finalx 于 2010-1-11 10:41 发表
[posted by wap, platform: BlackBerry]

让我想想起编译原理这课程了,以前看linker and loader 看的脑袋大,mb,看完了以后在也不碰计算机了。。。
具体问题具体分析就容易理解了,编程完全是实践性技能,空谈理论和放P没区别,写过1W行代码的人就是比写过5K行代码的人牛逼2倍,智商差别可以忽略。不过我还是那句话,如果是应用层编程,确实不需要了解这些,把一个进程在内存中各个段的意义搞清楚就行了

TOP

高级语言可以直接访问硬件的,而且语法上比汇编更简洁。能不能访问硬件关键看程序运行在cpu的什么级别上,用户空间是cpu运行在低权限级别,OS把部分地址用mmu保护了,也没有地址映射的接口,这才是无法访问到硬件的原因

TOP

有官网公开的datasheet,要是觉得这还不够可以去找找开源项目中的驱动代码,分析它的寄存器操作。有的厂家甚至还直接提供详细的寄存器操作步骤方法和demo代码示例,这得看你公司什么来头了

TOP

发新话题
     
官方公众号及微博