编译器为什么会生成汇编语言而不是机器语言?

是否会涉及到多平台、多主机的兼容性?
求此问题的详细解释

1)其中有一个好处是方便优化,因为,编译器也是工具,也是机器,毕竟是机器生成的程序,不可以非常 完美的,而汇编是机器指令的助记符,一个汇编指令就对应一条机器指令(特殊指令除外)调试起来肯定会比 机器指令方便的方便,这样优化起来也方便。
2)高级语言只需要编译成汇编代码就可以了,汇编代码到机器码的转换是由硬件实现即可,有必要用软件实 现这样分层可以有效地减弱编译器编写的复杂性,提高了效率.就像网络通讯的实现需要分成很多层一样,主要 目的就是为了从人脑可分析的粒度来减弱复杂性.
3)如果把高级语言的源代码直接编译成机器码的话,那要做高级语言到机器码之间的映射,如果这样做的 话,每个写编译器的都必须熟练机器码。这个不是在做重复劳动么。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-06-29
计算机只能识别二进制代码,所以机器指令是由二进制代码组成的,即你所说的机器语言。所谓汇编语言,只是一种符号,用来方便人们使用,否则你看到的都是一串串的01011011之类的信息,一眼就认出它是什么指令非常困难,而用汇编语言这种符号,一看就知道是什么指令了。这种符号语言用助记符来表示操作码,用符号或符号地址来表示操作数或数地址,它与机器指令是一一对应的。(楼上各位表述的所谓“步骤”论是不确切的)
所以,并不是你说的“生成汇编语言而不是机器语言”,生成的是机器语言,你在调试器或反汇编程序中看到的汇编语言代码只是由反汇编程序把机器指令翻译成你看得懂的符号--汇编语言--而已。(比如你在OD或IDA中可以看到每行汇编指令前面都有机器码,如push ebp的机器码是55h,单看55,你不是熟手的话可能还不知道它是什么指令,后面给你显示出符号"push ebp",你一下子就明白了,这就是一一对应的关系,连"55"都是为了让你看的方便,否则应是01010101,即8个电子元件的电源开、关状态)
同样的道理,你在十六进制编辑器(如winhex、HexWorkShop等软件)中看到的是十六进制每行16字节排列的,那也是经过把二进制代码每字节转换成十六进制显示给你看的。

关于平台问题,当然会有影响,不同的CPU有不同的指令系统,就连同一厂家的CPU指令系统都不同,比如Intel公司的CPU,从最早的到现在的,指令不断增多,什么MMX、SSE等等新指令集不断出现,更不要说不同厂家的CPU了。当然它们之间也有很多兼容的指令集。本回答被网友采纳
第2个回答  2013-06-28
不涉及多平台。您问的问题本身就是不正确的,编译器最后生成的就是机器语言。生成汇编语言只是一个步骤,生成了汇编语言之后,汇编语言与机器指令一一对应,生成机器语言十分容易。编译的过程分为词法分析,语法分析,语义分析,语法制导的翻译,中间代码生成等,要一步一步的来。建议你去看看《编译原理》
第3个回答  2013-06-28
什么语言的编译器?
C/C++编译器生成汇编清单,然后再生成机器码(本地)
C#.net vb.net生成MDIL(.net中间语言),然后运行时由系统实施编译为机器码(托管)
java生成java虚拟机机器码,(-.-)追问

其实我在看《汇编原理》这本书,其中所指语言应是指C/C++语言吧。。。
微软的中间语言应为MSIL(Microsoft Intermediate Language)可能是您手误吧。
不过您所提的诸多语言都需要转换成汇编或伪汇编语言(java的虚拟机码在下不是很清楚),但上述语言为何均不能直接转换为机器码呢?

追答

直接转换就实现不了,或比较困难实现一些语法上的功能了,比如命名约定,UNICODE支持

C的命名约定,函数名+@+参数大小 比如Hex(LPCSTR dest ,LPCSTR source)就为Hex@8
C++的命名约定,函数名+@+参数大小+ 乱码 比如Hex(LPCSTR dest ,LPCSTR source)就为Hex@8A#0C

所以C不能重载函数,C++可以

C\C++先生成汇编清单(若不设置生成清单文件,只会留在内存中),
然后用汇编清单到汇编编译器(ml.exe)
16位生成omf对象文件(obj)
32位生成coff对象文件
再用对应的16\32\64位连接器(link.exe)连接各个对象文件
运行时调用对应系统的加载器..

这样做的原因是,已经花费巨大人力物力创造的ml.exe不能这样浪费了,可以节省开支,而且底层高手很难招聘

本回答被提问者采纳
第4个回答  2013-06-28
C C++ 先生成汇编 OBJ 再通过汇编 生成对应的机器码
相似回答