首页 > 编程语言 >"hello world"程序的背后

"hello world"程序的背后

时间:2023-08-05 17:47:48浏览次数:28  
标签:文件 gcc 汇编 程序 hello 编译 world 链接

​ 今天浅浅分享一下一个hello程序的背后发生了什么

​ 首先创建一个hello.c程序

#include <stdio.h>
 
int main()
{
 printf("Hello World\n");
 return 0; 
} 

​ 其实上述过程可以分解为4个步骤,分别是预处理、编译、汇编、链接,如图所示

image-20230805165606337

预处理

​ 首先是源代码文件hello.c和相关的头文件,如stdio.h等被预编译器cpp预编译成一个.i文件。对于C++程序来说,它的源代码文件的扩展名可能是cpp或.cxx,头文件的扩展名可能是.hpp,而预编译后的文件扩展名是.ii.第一步预编译的过程相当于如下命令(-E 表示只进行预编译):

$gcc -E hello.c -o hello.i

image-20230805171912851

预编译过程主要处理那些源代码文件中的以“#”开始的预编译指令。比如“#include"、“#define”等,主要处理规则如下:

1、将所有的“#define" 删除,并且展开所有的宏定义。

2、处理所有条件预编译指令,比如“#if”、 “#ifdef"、 “#elif"、 "#else"、 “#endif"。

3、处理“#include"预编译指令,将被包含的文件插入到该预编译指令的位置。注意,这个过程是递归进行的,也就是说被包含的文件可能还包含其他文件。

4、删除所有的注释“//”和“/* */”。

5、添加行号和文件名标识,比如#2“hello.c"2,以便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号。

6、保留所有的#pragma编译器指令,因为编译器须要使用它们。

经过预编译后的.文件不包含任何宏定义,因为所有的宏已经被展开, 并且包含的文件也已经插入到.i文件中。所以当我们无法判断宏定义是否正确或头文件包含是否正确时,可以查看预编译后的文件来确定问题。

编译

​ 编译过程就是把预处理完的文件进行一系列词法分析、 语法分析、语义分析及优化后生产相应的汇编代码文件,这个过程往往是我们所说的整个程序构建的核心部分,也是最复杂的部分之一。简单介绍编译的具体几个步骤,这涉及编译原理等一些内容,仅仅是介绍而己。上面的编译过程相当于如下命令:

$gcc -S hello.i -0 hello.s

image-20230805172007327

现在版本的GCC把预编译和编译两个步骤合并成一个步骤,使用一个叫做ccl的程序来完成这两个步骤。这个程序位于“/usr/ib/gcc/i486-linux-gnu/4.1/"。

都可以得到汇编输出文件hello.s。 对于C语言的代码来说,这个预编译和编译的程序是ccl,对于C++来说,有对应的程序叫做cclplus; Objective-C 是cclobj: fortran 是f771; Java 是jc1.所以实际上gcc这个命令只是这些后台程序的包装,它会根据不同的参数要求去调用编译编译程序cc1、汇编器as、链接器ld。

汇编

​ 汇编器是将汇编代码转变成机器可以执行的指令,每一个汇编语句几乎都对应-条机器指令。所以汇编器的汇编过程相对于编译器来讲比较简单,它没有复杂的语法,也没有语义,也不需要做指令优化,只是根据汇编指令和机器指令的对照表-一-翻译就可以了,“汇编”这个名字也来源于此。上面的汇编过程 我们可以调用汇编器as来完成:

$as hello.s -o hello.o

或者:

$gcc -C he1lo.s -o hello.o

image-20230805172041809

链接

​ 链接通常是一个让人比较费解的过程, 为什么汇编器不直接输出可执行文件而是输出一个目标文件呢?链接过程到底包含了什么内容?为什么要链接?这恐怕是很多读者心中的疑感。正是因为这些疑感总是挥之不去,所以我们特意用这章的篇幅来分析链接, 具体地说分析静态链接的章节。下面让我们来看看怎么样调用Id才可以产生一个能够 正常运行的HelloWorld程序:

$1d -static /uar/1ib/ert1.o /uer/11b/crt1.o

/u6r/11b/gcc/1486-11nux-gu/4.1.3/ertbegint.o

-L/u8r/11b/gcc/1486-11nux-gou/4.1.3 -L/u8x/11b -L/l1b hello.o--8tart-group-1gcc -1gcc _eb -1c --end-group /uar/1b/gcc/1486-11mux- gou/4.1.3/ertend.o/u8r/11b/crtn.o

如果把所有的路径都省略掉,那么上面的命令就是:

d -static crt1.o crti.o crtbegint.o hello.o -start-group -1gcc -lgcc_ eh -1c-end-group crtend.o crtn.o

可以看到,我们需要将一大堆文件 链接起来才可以得到“a.out",即最终的可执行文件。看了这行复杂的命令,可能很多读者的疑感更多了,crtl.o. cri.o、crtbeginT.o crtend.o、crtn.o这些文件是什么?它们做什么用的? -lgcc -lgcc _eh -lc这些都是什么参数?为什么要使用它们?为什么要将它们和hello.o链接起来才可以得到可执行文件?等等。

这些问题它们看似简单,其实涉及了编译、链接和库,甚至是操作系统的一 些很底层的内容。

这就是一个hello程序背后的内容了,其实后面还有更加细节的语法分析、词义分析、有限状态机等等知识,有兴趣的读者可以自行百度,这里不再赘述。

标签:文件,gcc,汇编,程序,hello,编译,world,链接
From: https://www.cnblogs.com/dwinternet/p/17608294.html

相关文章

  • Linux系统下将java程序开机自启
    Linux系统下将java程序开机自启在Linux环境下,可以通过将Java程序配置为系统服务(systemd服务)来实现开机自启动。使用systemd可以很方便地管理和控制后台服务,包括Java程序。以下是一个简单的步骤来配置Java程序为systemd服务:1.编写启动脚本创建一个脚本文件,用于启动您的Java程序......
  • 赋能智慧医疗:构建高效电子处方小程序的技术要点
    时下,医疗行业也开始积极融合信息技术,将智慧医疗带入现实。其中,电子处方作为智慧医疗的重要组成部分,为传统的纸质处方带来了革命性的改变。电子处方小程序的出现使医生和患者能够更加高效地管理和获取处方信息,本文将就如何构建高效电子处方小程序进行探讨。一、数据安全的重要性在构......
  • Abaqus 中最常用的子程序有哪些 硕迪科技
    在ABAQUS中,用户定义的子程序是一种重要的构件,可以将其插入到Abaqus分析中以增强该软件的功能和灵活性。这些子程序允许用户在分析过程中添加自定义材料模型、边界条件、初始化、加载等特定操作,以便更精准地模拟分析中的现象和现象。ABAQUS支持各种不同类型和用途的子程序,下面列举了......
  • 鸿蒙生态星河璀璨 | 老程序员让HarmonyOS创新从“心”开始
    “技术上有过一段时间,自己的自信心变成了自负,尤其是在30岁出头那段时间,遇到了很大的瓶颈期。” 苏煦烽回忆十多年前的自己,由于每天做着重复的事情,都在写代码,也很难找到特别牛的高手来交流,曾有过短暂的停滞不前。从2006年到现在,老苏在程序员之路上已经摸爬滚打了十七年,如今他已是......
  • #yyds干货盘点# LeetCode程序员面试金典:课程表
    题目:你这个学期必须选修numCourses门课程,记为 0 到 numCourses-1。在选修某些课程之前需要一些先修课程。先修课程按数组 prerequisites给出,其中 prerequisites[i]=[ai,bi],表示如果要学习课程 ai则必须先学习课程 bi。例如,先修课程对 [0,1]表示:想要学习......
  • #yyds干货盘点# LeetCode程序员面试金典:统计各位数字都不同的数字个数
    1.简述:给你一个整数n,统计并返回各位数字都不同的数字x的个数,其中0<=x<10n 。 示例1:输入:n=2输出:91解释:答案应为除去11、22、33、44、55、66、77、88、99外,在0≤x<100范围内的所有数字。示例2:输入:n=0输出:12.代码实现:classSolution{publicintcount......
  • [8月摸鱼计划] 电脑经常出现” 显示器驱动程序已停止响应“
    出现这个问题主要在看视频时或玩游戏中,屏幕突然黑屏,过了几秒后恢复正常,并在任务栏右下角提示“显示器驱动程序已停止响应,并且已成功恢复”的对话框。解决方法:一、重新安装升级显卡驱动。使用到的软件“驱动精灵”1、运行驱动精灵软件,弹出的主界面单击“驱动程序”选项2、在标准......
  • 源代码质量对程序竞争力的重要性
    源代码质量对程序竞争力的重要性     在当今快节奏的软件开发领域,源代码质量直接关系到一个企业或个人在市场竞争中的地位和竞争力。本文将探讨源代码质量对程序竞争力的重要性,并阐述如何通过优化源代码质量来增强程序竞争力。我个人也经常对初级软件工程师的建议能写好高质......
  • 本地启动 ABAP Platform Trial 的 Docker 命令行程序
    Docker是一个开源的容器化平台,用于轻松地构建、发布和运行应用程序。DockerDesktop是适用于Windows和Mac的Docker桌面应用程序,它允许用户在本地运行和管理容器化应用程序。在本文中,我们将详细介绍以下两个命令行并解释每个参数的含义:dockerpullsapse/abap-platform-trial:1909......
  • 新的 Anaconda Web UI 安装程序可能会随 Fedora 工作站 39 一同推出
    导读新的AnacondaWebUI安装程序可能会随Fedora工作站39一同推出。长期以来,Fedora的安装体验一直未曾改变。然而,这个新的WebUI安装程序已经开发了一年多的时间,现在离正式实现的目标更近了。为什么现在是时候了?在我们上次了解即将到来的AnacondaWebUI安......