java变c_C、Java代码如何变成计算机指令

java - 字节码 - 虚拟机 - 机器码 - CPU执行

C 语言代码 ―编译―》汇编代码 ―翻译―》机器码

机器码是 CPU 能识别的语言,由 0、1 组成。

一条条机器码就是一条条计算机指令。

汇编代码一一对应机器码。汇编语言就是为了让人方便阅读机器码的。

不同的 CPU 能识别的计算机指令集不一样,即支持的汇编代码也不一样。

C 语言代码 -》机器码,其实有两个阶段: 通过编译、汇编、链接,生成一个可执行文件。

把可执行文件装载到内存,CPU 从内存读取指令和数据,开始执行程序。

由汇编器翻译成机器码时,生成的是一个目标文件(.o文件,是二进制文件)。该目标文件还需要通过链接,比如把调用的库函数(也是目标文件)合并处理,生成可执行文件,才能装载到内存,让 CPU 执行。

可执行文件,在 Linux 中是 ELF 文件格式,里面包含着符号表(函数、全局变量等的地址)和数据段、代码段等。

在硬盘中的可执行文件被加载到内存后,CPU 会从内存读取指令和数据。

CPU 核心组件包括:PC、寄存器、ALU。

PC 程序计数器指向内存地址,CPU 根据 PC 加一顺序获取下一条指令。

寄存器可以存储数据,CPU 从内存获取数据加载到寄存器。

ALU 算术 / 逻辑单元可根据寄存器中的数据进行计算,并把结果再放到一个寄存器里。

CPU 可把寄存器中的数据再放到内存中。

把可执行文件装载到内存。

加载后占用的内存空间是连续的。

这里指令用到的内存地址指的是虚拟内存地址,而实际在内存硬件中的地址,叫物理内存地址。

系统需要维护一个虚拟内存地址到物理内存地址的映射表――页表。

关于如何映射,有内存分页技术:即把物理内存、虚拟内存分成一段段固定的大小,叫页。映射时按页来做映射。

通过分页,操作系统在加载程序时,不需要一次性加载到物理内存。可以在真正执行程序时,如果需要再把页加载到物理内存中。(发现没有加载到内存时 CPU 会触发缺页错误)

所以,内存空间连续是指页内连续。

(自「深入理解计算机系统 7.9 加载可执行目标文件」)

当 shell 运行一个程序时,父 shell 进程生成一个子进程,它是父进程的一个复制。子进程通过系统调用启动加载器。

加载器删除子进程现有的虚拟内存段,并创建一组新的代码、数据、堆、栈段。新的栈、堆段初始化为零。通过将虚拟地址空间中的页映射到可执行文件的页大小的Ƭ,新的代码、数据段被初始化为可执行文件的内容。――内存映射

最后,加载器跳转到程序入口地址开始调用应用程序的 main 函数。

除了一些头部信息,在装载过程中不会从磁盘复制数据到内存。直到 CPU 引用一个被映射的虚拟页时,才会进行复制。

为了满足程序对内存的需求,一般虚拟内存大于实际的物理内存。如果发生映射到相同的物理内存地址,或者找不到空闲的物理内存时,系统一般会找出不常用的内存,把该已经被占用的物理内存挪到硬盘(如 Linux 里的 swap 硬盘分区)里,让当前程序使用该物理内存空间。

但由于硬盘访问速度比内存慢很多,所以频繁出现内存交换,会降低性能。

链接是将各种代码、数据片段合并成一个可执行文件的过程。

链接可发生在编译时、加载到内存时、运行时(应用程序来执行)。

有了链接,就可以模块化、分开编译,不需要每次都要形成一个大文件,只需要编译有修改的模块,让链接器来进行合并。

链接做的主要工作: 符号解析:目标文件中定义、引用的符号,是对应着一个函数、全局变量、或静态变量。链接器需要把每个符号引用和一个符号定义关联起来。

Java 的重载:Java 能使用重载,是因为编译器为各方法编码成了对链接器来说唯一的名字。这种编码过程叫做重整。

重定位:目标文件都是从地址 0 开始的。链接器需要把每个符号定义与一个内存关联起来,然后修改所有对这些符号的引用,使得它们指向这个内存位置。

需要每次都要复制一份放到可执行文件里,很占硬盘、内存空间。

所以出现动态链接思路。

不根据存储在硬盘里的目标文件,而是根据已经加载到内存中的共享库进行链接。即内存中只需要一份库函数代码。

共享库,在 Linux 是 .so 文件,在 Windows 中是 .dll 文件,一般也叫动态链接库。

各程序使用的动态链接库的物理内存地址相同,但虚拟内存地址是不同的。

Java 的 JNI 就是调用 C / C++ 函数。其基本思想是将 C 函数编译到共享库中。在运行时调用 JNI 接口时,通过操作系统提供的接口,进行动态链接和加载该可执行文件,然后再调用其函数。

来源:博客园

作者:dmsdus

链接:https://www.cnblogs.com/dmsdus/p/11456941.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值