深入浅出C语言(1) ----编译器的作用

在学习C语言的时候,一般人可能着重点在于C语法上,忽略了编译器的作用。

而真正深入理解C语言是绝不能离开编译器的。C语言跟其他诸如C++Java,C#Perl等应该算是一种符号标准,真正实现这种标准的是-----编译器。

 

C语言写的源代码程序,最终是要运行在CPU上的。对于CPU来说,它能识别是二进制代码。所以C程序最终要被翻译成二制码才可以运行。

C到二进制码可以有两种方式来实现:

1.       人工翻译

2.       C语言编译器来翻译

 

人工翻译:

选一条C语言中比较简单的语句,

While(1); //这是一条无限循环语句

X86体系下,它对应的汇编代码为: 0: jmp 0

0: jmp 0这句机器代码的意思是: CPU执行某个地址的代码时,在这条地址上跳转到自己地址上去。大家知道汇编本质是二进制指令的助记符,所以在某个体系结构下都会有的CPU汇编指令与二进制的对应表。例如8086 CPU下, jmp对应的指令为:11011001,即十六进制的E9。根据这些资料,就可以得出对应汇编语句的代码了。

综上所述:人工翻译C到二进制代码,需要以下东西:

1.       CPU的指令结构

2.       CPU的二进制指令与汇编指令的对应表 

3.       用汇编代码来表示C语言所表达的语句

有了上面的东西,就可以直接进行二进制代码编程了。在windows下,DOS格式是一种可执行文件格式,我们可以构造dos的文件头,再填入二进制代码,然后就能被windows加载到CPU执行了。甚至你可以对现有的exe软件进行分析,植入自己的二进制代码,调整相应的exe参数,这样,当执行这个exe时,你的代码也会被执行啦。

 

C编译器翻译

C语言编译器就是代替人工翻译而存在的,本质是一样,只不过,编译器实现了更强大的功能而已。C语言编译器编译流程大体是这样的:

C源代码->编译预处理->编译->汇编程序->链接程序->可执行文件

也就是说,从C源代码到可执行文件,C语言编译器起到了至关重要的作用。

在正式了进入C编译器编译C语言之前,我们可以思考以下几个问题:

1.       通常汇编程序比C语言效率更高,为什么?
C编译器也会把C代码转成汇编,不过编译器在转化的时候,生成了更多的汇编代码。实现同样的功能,直接写汇编写可能就只有10行,但用C语言写的代码经过编译器转化的时候,就变成了20行汇编了。

2.       我们可以看C#写的exe程序可以反编译C#代码,而C语言写的代码编译后为什么不能反编译为C代码?
C
语言编译的可执行程序中的二进制代码因为有二进制与汇编指令对应表,所以可以反编译为汇编。从汇编是难于反编译为C语言的,因为逻辑上不好转换。

C#编译的程序可以反编译是因为它生成的程序并不包含真正的二进制代码,那它是怎么运行的呢??你可能猜到了,就是由于.Net Framework模架才负责转化成真正的代码的。 Java也是类似。

3.操作系统也是用C语言写的,编译编译后为什么既可以装在Intel系列的CPU上,也可以装在AMD系列的CPU上?

   理由是:它们采用兼容的指令体系。如果不兼容的时候,那操作系统就得为每种CPU都做一份编译了。

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试