‘壹’ C语言代码编译成的是机器码,那么怎么实现可移植性呢
C语言代码编译成的是机器码,通常不能在不同指令系统的机器上运行。
我遇到过同样的机器,同样的机器码,同样的操作系统,也就是原来在本机编好的若干程序,突然运行不了了(出错),必须重新编译后才能运行。因为微软动态链接库里的子程序号码“更新”了。
如果编译成半成品机器码,或者类似obj,到运行的机器上再由附加的解释器解释(或编译器链接),则可以运行。这就是所谓的“跨平台”“移植”“嵌入”。
‘贰’ 请问c语言的源程序被编译后的代码是机器码吗
首先语言和被编译成的代码没有直接关系。有把java编译成机器码的编译器也有把C语言编译成Java字节码的编译器。
机器码只是CPU直接认读的编码,不等于和硬件打交道的。操作硬件是你通过程序操作CPU做到的。操作系统只不过是别人写的程序而已,说到底还是程序。
‘叁’ C语言编译后是生成汇编代码还是直接生成机器代码
不会是这两种语言代码,而是编译后直接生成二进制文件(.obj文件),再通过连接器链接成二进制文件(.exe/.dll/.ocx/.sys等)
‘肆’ 在计算机中,将汇编语言转换为机器语言的过程叫
在计算机中,将汇编语言转换为机器语言的过程叫汇编,或者汇编过程。
汇编语言称为符号化的机器语言,不能直接执行,需要将汇编语言转换为机器语言后才能执行,将汇编语言程序转换为机器语言程序的过程称为汇编过程。
汇编大多是指汇编语言,汇编程序。把汇编语言翻译成机器语言的过程称为汇编。在汇编语言中,用助记符(Memoni)代替操作码,用地址符号(Symbol)或标号(Label)代替地址码。这样用符号代替机器语言的二进制码,就把机器语言变成了汇编语言。于是汇编语言亦称为符号语言。用汇编语言编写的程序,机器不能直接识别,要由一种程序将汇编语言翻译成机器语言,这种起翻译作用的程序叫汇编程序,汇编程序是系统软件中语言处理的系统软件。
‘伍’ C语言翻译成机器码,一定先要翻译成汇编吗
是的
编译器是先转成汇编代码
然后再转成机器码
也就是二进制
‘陆’ 能否将C#代码直接编译成机器代码
很抱歉,这是不可能的。C#语言程序不可能脱离.net框架,就像Java一样,C#语言的运行环境是.net framework,.net对于C#就像Java虚拟机对于Java语言一样。另外,C#是一种有限制语言,.net负责保证代码访问的安全特性,C++是唯一可以允许程序员开发无简大局限制低级程序的语言,.net不仅负责为代码提供运行支持,还负责保证程序的安全性,一种受限制的语言是不能脱离限制程序的控制的,对于C#,.net就是控制系统,因此,C#程序不可能脱离.net环境。
===================================================
对补充的答复:
这恐怕也是不行的。在以往的PE结构的程序中,因为不同的CPU拥有不同的指令集,所以为了适应客户机的硬件的不同,往往会开发一个程序的不同版本,微软为了解决这个问题,在.net中准备了多个即时编译器(JIT),当一个中间语言的程序在客户机上运行时,JIT会根据客户机当前的硬件配置和操作系统等方面的情况对代码进行优化,然后生成本地化的机器代码,这个机器代码并不是全部程序的代码,而是只生成程序运行必须的部分,其它的会在执行时根据需要动态生成。微软官方对项技术的解释为:
“JIT 编译考虑了在执行过程中某些代码可能永远不会被调用的事实。它不是耗费时间和内存将可移植可执行 (PE) 文件中的所有 MSIL 转换为本机代码,而是在执行期间根据需要转换 MSIL 并存储生成的本机代码以供后继的调用使用。当加载类型时,加载器创建存根 (stub) 并将其附加到类型的每个方法。当对方法进行初始调用时,存根 (stub) 将控制传递给 JIT 编译器,而编译器将该方法的 MSIL 转换为本机代码并修改存根 (stub) 以直接执行到本机代码的位置。后仿滑面对 JIT 编译的方法的调用将直接进行到以前生成的本机代码,从而减少了进行 JIT 编译和运行代码所需的时间。”(原文)
此外,当一个程序开始运行后,JIT首先开始进行即时编译,当某个被编拦让译过的方法被再次执行时,将直接执行它的本地代码。
希望这些信息对您有所帮助。
‘柒’ 怎么把 汇编代码 转成 机器码
将这些代码写入一个.asm文件,加上必要的程序框架,用汇编程序汇编处理一下就可以得到你要的机器代码了。
因为你列出的这些代码是32位的指令,汇编程腊握尺序中要加上.386伪指令
以你列出的这三条指轮高令为例,你可以这样写一个程序:
.386
.code
.startup
mov eax, 0040100FH
jmp eax
add edx, 4
end
用TASM汇编程序汇编,在命令行里加上 /l 选项,汇编后查皮昌阅生成的.lst文件,可以得到这三条指令的十六进制的机器代码为:
B8 0040100F (按字节拆开是 B8 0F 10 40 00)
FF E0
83 C2 04
‘捌’ 后缀为exe的文件本身是机器码吗C++编译过的程序是机器码么。但是java好像也能做出exe程序。
exe文件是机器码
只要遵循exe文件格式进行编译链接就可以制作exe,并非某一编译器特有
c++直接编译成二进制机器码,可以在机器上直接运行,而java先将代码编译成字节码,再依靠java虚拟机模拟cpu运行程序,性能上有损失
解释型编译器并不直接产生二进制机器码,而是中间码 需要特定的软件先解释成二进制码才可运行
如脚本,这种方法灵活性强,修改代码无需重腊樱新编译,但性能塌局液会损团物失,
编译型则直接产生二进制代码,无需软件支持,靠硬件即可运行,这种方法速度快,但灵活性不足,每次修改都需要重新编译。
java属于混合型,产生的不是中间码 而是字节码 java虚拟机不解释成机器码 而是模拟cpu运行,所有java称虚拟机,而不是解释器
‘玖’ 编译器为什么会生成汇编语言而不是机器语言
计算机只能识别二进制代码,所以机器指令是由二进制代码组成的,即你所说的机器语言。所谓汇编语言,只是一种符号,用来方便人们使用,否则你看到的都是一串串的01011011之类的信息,一眼就认出它是什么指令非常困难,而用汇编语言这种符号,一看就知道是什么指令了。这种符号语言用助记符来表示操作码,用符号或符号地址来表示操作数或数地址,它与机器指令是一一对应的。(楼上各位表述的所谓“步骤”论是不确切的)
所以,并不是你说的“生成汇编语言而不是机器语言”,生成的是机器语言,你在调试器或反汇编程序中看到的汇编语言代码只是由反汇编程序把机器指令翻译成你看得懂的符号--汇编语言--而已。(比如你在OD或IDA中可以看到每行汇编指令前面都有机器码,如push ebp的机器码是55h,单看55,你不是熟手的话可能还不知道它是什么指令,后面给你显示出符号"push ebp",你一下子就明白了,这就是一一对应的关系,连"55"都是为了让你看的方便,否则应是01010101,即8个电子元件的电源开、关状态)
同样的道理,你在十六进制编辑器(如winhex、HexWorkShop等软件)中看到的是十六进制每行16字节排列的,那也是经过把二进制代码每字节转换成十六进制显示给你看的。
关于平台问题,当然会有影响,不同的CPU有不同的指令系统,就连同一厂家的CPU指令系统都不同,比如Intel公司的CPU,从最早的到现在的,指令不断增多,什么MMX、SSE等等新指令集不断出现,更不要说不同厂家的CPU了。当然它们之间也有很多兼容的指令集。
‘拾’ 编译器是什么意思,是做什么的
编译器
编译器是一种特殊的程序,它可以把以特定编程语言写成的程序变为机器可以运行的机器码。我们把一个程序写好,这时我们利用的环境是文本编辑器。这时我程序把程序称为源程序。在此以后程序员可以运行相应的编译器,通过指定需要编译的文件的名称就可以把相应的源文件(通过一个复杂的过程)转化为机器码了。
下面我们看看它是如何工作的。首先编译器进行语法分析,也就是要把那些字符串分离出来。然后进行语义分析,就是把各个由语法分析分析出的语法单元的意义搞清楚。最后生成的是目标文件,我们也称为obj文件。再经过链接器的链接就可以生成最后的可执行代码了。有些时候我们需要把多个文件产生的目标文件进行链接,产生最后的代码。我们把一过程称为交叉链接。
有一个称为LCC的编译器,还挺不错的;还有一个用于分析其规则的小工具;