从源代码到可执行文件

在理解一个源代码是如何成为可执行文件时,我简单的回顾下硬件层面、操作系统层面的知识。开机启动一BIOS扫描基本设备,cpu、memory、displayetc,从硬盘启动,读盘面1磁道1扇区1

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

在理解一个源代码是如何成为可执行文件时,我简单的回顾下硬件层面、操作系统层面的知识。

 

开机启动

一 BIOS扫描基本设备,cpu、memory、display etc,从硬盘启动,读盘面1磁道1扇区1的内容进入内存,这段内容是操作系统引导程序

 

二 cpu的任务是计算,不同的cpu制定了一套instruction set,通过调用指令集,输入数据,输出数据

 

三 DMA directly memory access 主存,数据存储介质,读写速率高,满足对cpu的数据输入输出

 

四 操作系统 负责用户资源(进程、内存、文件系统、硬件设备etc)的管理、调度、安全

 

 

以上是我们在开机后做的工作,大量的、复杂的工作,而我们确实享受者。

 

 

我们开始编写源代码,然后编译执行。我们感觉到自己非常厉害,其实我们仅仅做了一点点东西。

 

1 编译器

源代码通过编译器变成汇编文件。

编译器做的主要工作就是根据语言,词法、语法分析,将面向对象的、面向过程的高级语言翻译成汇编语言。

我认为编译器应该是建立在操作系统上的,因为不同的cpu的汇编语言存在差异,所以编译器无法跨硬件平台,需要与操作系统匹配。

java的编译与c c++的编译,我们称之为传统的编译,是不同的,java的编译是生成字节代码,也就是JVM能够读懂的代码,这是一种中间代码。)

在编译的过程中,所有的全局变量在内存中的标识是虚拟地址,而不是我们在开发过程中定义的名称。例如int a = 1;这里的a在汇编代码中就不存在了,取而代之的是一个地址。在汇编文件中有一个符号表,它指明了这个地址的名称为a,以及其他信息,用于以后的debug。由于并非是可执行文件(在可执行文件中所有变量、调用的地址才能真正确定),这些地址是未确定的,所以对于这些数据(变量、函数)有relocation table,需要在最后的链接过程中对全局变量、函数做relocation

 http://hovertree.com/

2 汇编器

通过汇编器,将之前的汇编代码,转行成机器语言。但格式并非是纯执行代码。

这个时候生成目标文件,文件有不同的段组成,head、text、date、symbol、string、relocat等等

 

3 linker 链接

linker 就是将目标文件合并,符号解析、重定向。

合并,就是多个obj组合为一个,一个lib或者elf执行文件

重定向,由于地址程序执行代码的地址可以确定了(多亏了操作系统的虚拟内存,每个程序的虚拟内存空间地址都是一样的),之前我们无法确定地址的变量、函数以及由于合并而受到影响的变量、函数都可以给一个地址了。

符号解析,前面的地址都变化了,符号表中内容要更新

 

4 loader 加载

最后我们运行程序,加载之前linker好的elf文件。

在内存中画一片空间,几个重要的区域。静态code文件区,全局变量区,heap区,stack区。

stack区:是程序运行的动态执行流。我们平时看的程序在做些什么,就打threaddump、processdump实际上就是看stack中的内容。

如果这个时候符号表中的内容在gcc编译时保留了,那么我们可以看到详细的系统调用过程。在linux中我们用lstack和strace可以看程序的stack。

heap区:这个是在程序中deveploer制定分配的区间,用来保存数据,c是面向过程的,所以对内存的分配比较容易理解,nmap函数,分配多少字节等等,最后还要释放这些空间,否则会出现内存泄露。对于面向对象语言java,可能了解起来就比较麻烦,因为java编译器为我们做了一个面向对象到面向过程的转换。但是不变的是我们实例化一个对象,就必须nmap一个区间给这个实力。对于这个实例的attribute属性进行保存,而method方法则无需,因为他是执行流,也就是code,通一个类的所有的实例的method是一样的,在静态code区有method的执行代码。

stack和heap的关系:当然stack中持有了大量heap的reference,比如java,两个类的执行流一样,但是reference不同,只想heap不同的区域,代表不同的实例。

stack中要注意的就是push and pop,他是函数调用、参数传递的主要手段。

动态链接:动态链接库是通过loader来做重定向。在加载时我们并不将库放入内存,而是在运行时通过虚拟内存将一份代码映射到多个程序中。

 

上是对source code to execute file baisc understand.随笔书写,加深记忆。

推荐:http://www.cnblogs.com/roucheng/p/texiao.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/120460.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • go语言要学多久才能工作_go语言可以开发什么

    go语言要学多久才能工作_go语言可以开发什么我在2011年就听说了Go并学习了一段时间,坦白的说,那时候对Go是比较无感的,因为并没有看到Go的特别亮眼的地方,可能和我使用C、Erlang、Java有关,这三种语言可以写高性能、高并发、高可用的服务;包含了面相过程、面向并发、面向对象的思想,我觉得我并不需要再学习Go,何况那个时候好像也没宣传的那么优秀。 一切都发生在418天前,因为工作的需要,我开始写Go了,本来预期是一段压抑、蛋疼的旅程

  • c语言匹配字符串表达式函数_java字符串匹配

    c语言匹配字符串表达式函数_java字符串匹配最近在写一个程序,需要用到字符串匹配,并且返回匹配的字符串,C语言库函数中的strtstr无法满足我的要求,只能自己写了。代码如下//stringmatchfunctionchar*matchString(constchar*buf,constchar*sub){ char*tbuf=buf; char*tsub=sub; inti=0;//tbuf…

  • openssl升级后ssh登录失败(无尽升级)

    OpenSSL升级3.0.0openssl官方下载地址:https://www.openssl.org/source/1.编译tarxfopenssl-3.0.0.tar.gzcdopenssl-3.0.0./config–prefix=/usr/local–openssldir=/usr/local/opensslmake&&makeinstall2.1备份原来的opensslmv/usr/bin/openssl/usr/bin/openssl

  • 直流无刷电机工作原理「建议收藏」

    直流无刷电机工作原理「建议收藏」直流无刷电机工作原理

  • 关系数据库基础理论[通俗易懂]

    关系数据库基础理论[通俗易懂]mysql系列之一关系数据库基础理论正是数据库管理的需要催生了数据库管理系统DBMS,而关系型数据库管理系统为RDBMS常见的数据模型有三种:-层次模型-网状模型-关系模型一、关系数据库的产生在DBMS出现之前,人们用文件来管理数据,但存在很多缺陷:1.数据冗余和不一致性。数据冗余表示在每个shell脚本中基本上都是/bin/bash,但很多用户使用…

    2022年10月16日
  • jmeter正则提取器用法_jmeter字符串截取

    jmeter正则提取器用法_jmeter字符串截取JMeter正则表达式提取器 转自:http://desert3.iteye.com/blog/1394934//提取HTML中隐藏域的值^(.*)$ //提取整个response返回提取MyLabel关联的input的值MyLabel”(.+:create:.+?)”  //提取下面link的href的值JSESSIONI

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号