javac编译器工作原理(1)高级语言的编译原理

javac编译器工作原理(1)高级语言的编译原理

众所周知,Java语言有自己的语言规范,这个规范描述了Java语言有那些词法和语法的,有繁多的关键字,有固定的语法,而Java语言本质意义上是一门高级语言,这种语言如何被计算机理解并由CPU执行,就要倚靠JVM和JVM内置的编译器来完成。

首先我们来了解一下,高级语言是如何编译成为低级语言并由计算机执行的

计算机是不能直接运行高级语言代码的,CPU识别的只有二进制的0和1,而早期的工程师们就定义了不同的0和1组成了机器码(Machine code)

机器码也叫做机器语言,是可以由计算机的中央处理单元(CPU)直接执行的一组指令。
每条指令执行一个非常特定的任务,例如对CPU寄存器或内存中的数据单元执行加载,跳转或ALU操作。
每个由CPU直接执行的程序都由一系列这样的指令组成。

而高级语言就需要把语言本身经过某种手段,转化为机器能识别的机器码,然后交由操纵系统处理,最终CPU才可以识别运行

这里我们以C语言的汇编过程为例。

C语言编译过程

可以看出,C语言代码的编译过程分为四步:

预处理->编译->汇编->链接

假设有一个C语言源文件 my.c

#include<sdtio.h>
int main(){
    printf("test");
}

在Linux使用gcc编译器,进行编译(注意此时直接完成了预处理和编译,得到了汇编代码)

gcc -S my.c 

编译完成的汇编代码如下:

    .file   "my.c"
    .section    .rodata
.LC0:
    .string "test"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    leaq    .LC0(%rip), %rdi
    movl    $0, %eax
    call    printf@PLT
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0"
    .section    .note.GNU-stack,"",@progbits

而这些汇编代码,经过第三步汇编生成二进制01机器码,机器码可以被CPU理解执行,这里说一下,汇编代码也只是机器码的一种语言表述,和机器码具有一一对应的关系
关于什么是汇编代码–维基百科

最后经过第四步,动态或者静态链接完成,生成的可执行的二进制代码即可由操作系统执行。

如果对上面的图和我说的还是不太理解,可以参考阮一峰大神的博客编译器的工作过程,值得一提的是对于不同的CPU架构,其汇编代码(Assembly Code)以及对应的机器码(Machine Code)是不尽相同的,比如x86汇编代码和ARM汇编代码,主要原因是因为不同CPU设计寄存器数目的不同等等。

而JVM的设计其实就和物理机一样,具有自己的堆、栈和执行引擎以及PC计数器

JVM结构体系

Java虚拟机就像物理机一样,同样是无法看懂Java代码的,所以就需要某种编译器将Java代码翻译成虚拟机能看懂的代码,类似物理机上CPU能读懂的机器码一样。JVM这种设计使得JVM这个平台更具开放性,无论是Java语言,还是JVM上的新成员Kotlin,Groovy等,最终还是要被某种编译器翻译成JVM能读懂的字节码。这些字节码,相当于物理机器能识别运行的机器码(或者对应的汇编语言)

而经过javac编译生成的.class文件,其实就是相当于编译过程中产生的汇编文件。


参考资料:
《深入分析Java Web技术内幕》–许令波
《深入理解Java虚拟机》–周志明
C语言编译过程详解
Java内存管理:深入Java内存区域

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值