您现在的位置是:首页 > 正文

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

2024-02-01 01:36:02阅读 2

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

网站文章

  • FairMOT理解与实现

    FairMOT理解与实现

    理解:(1)概述:多目标跟踪,单纯跟踪能力不足以完成任务,所以,不同于单目标跟踪,这里加入了检测任务,可以将多目标跟踪任务看成为目标检测+重识别任务。(2)论文网络结构:文中网络结构分3大部分:网络结...

    2024-02-01 01:35:53
  • 删除字符串中重复字符。

    题目:删除字符串中重复字符。如果可以,优先删除重复字符中排在比他小字符前面的字符。 比如,输入:bbcacdww;输出:bacdw 分析:如果根本不允许开设数组,则只能就地进行字符串去重,那么可以依次访问字符串中的字符,并删除从该字符串开始到结尾的所有相同字符。时间复杂度为O(n^2 )。void removeDuplicate(char s[]){ int i = 0; whil

    2024-02-01 01:35:46
  • VM下的Centos7安装ftp服务

    VM下的Centos7安装ftp服务

    Linux安装ftp组件1  安装vsftpd组件 [root@bogon~]# yum -y install vsftpd 2  配置vsftpd组件l  打开vsftpd配置文件/etc/vsftpd/vftpd.confl  配置文件的内容如下anonymous_enable=NO //设定不允许匿名访问local_enable=YES //设定本地用

    2024-02-01 01:35:39
  • matlab练习程序(广度优先搜索BFS、深度优先搜索DFS)

    matlab练习程序(广度优先搜索BFS、深度优先搜索DFS)

    如此经典的算法竟一直没有单独的实现过,真是遗憾啊。广度优先搜索在过去实现的二值图像连通区域标记和prim最小生成树算法时已经无意识的用到了,深度优先搜索倒是没用过。这次单独的将两个算法实现出来,因为算法本身和图像没什么关系,所以更纯粹些。广度优先搜索是从某一节点开始,搜索与其线连接的所有节点,按照广度方向像外扩展,直到不重复遍历所有节点。深度优先搜索是从某一节点开始,沿着其搜索到的...

    2024-02-01 01:34:59
  • win10 安装配置Git

    win10 安装配置Git

    3.继续,执行ssh-keygen-trsa,(注意ssh-keygen无空格),生成SSH(你的电脑与Gitee通信的安全连接)百度地址链接https//pan.baidu.com/s/1Y_P_e...

    2024-02-01 01:34:43
  • 机器学习概述

    简介什么是机器学习?机器学习就是从【数据】中自动分析,获得【规律(模型)】,并利用规律对未知数进行【预测】。样本数据(数据集)的载体- 通常情况下历史数据都不会存储在数据库中,而是存储在文件中(.cs...

    2024-02-01 01:34:37
  • Mysql 基于GTID的主从复制及切换

    参考http://imysql.com/tag/gtidhttp://mysqllover.com/?p=594Mysql 基于GTID的主从复制及切换一、主从复制配置两个mysql服务的my.cnf 中相关内容配置[mysqld]#从复制数据库表设置replicate-wild-ignore-table = mysql.%,information_schema.%,inno...

    2024-02-01 01:34:02
  • linux上传文件put,详解Linux ftp 命令行中下载文件get与上传文件put的操作方法

    尽管现在有许多好的FTP应用程序,但服务器命令行ftp命令的应用程序仍然很多,下面就让电脑乐园小编带你一起来学习详解Linux ftp 命令行中下载文件get与上传文件put的操作方法。介绍:从本地以...

    2024-02-01 01:33:55
  • 切面条问题

    切面条问题

    切面条问题 python

    2024-02-01 01:33:27
  • Java架构师面试题——JVM性能调优

    JVM内存调优 对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数。 1.Full GC 会对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对...

    2024-02-01 01:33:20