c程序是如何跑起来的01——普通可执行文件的构成(代码片段)

Mculover666 Mculover666     2022-11-30     231

关键词:

学习目的

  • 程序烧到什么地方?
  • 程序加载到内存什么地方?
  • 程序如何执行?

一、编译环境搭建

ubuntu 20.04使用arm-linux-gnueabihf-gcc 7.5.0。

二、程序源码

main.c:

#include <stdio.h>
#include "calc.h"

int main(int argc, char *argv[])

    int a, b;
    static int local_val = 2;
    static int uninit_local_val;

    a = add(2, 3);
    b = sub(5, 4);

    printf("a = %d\\n", a);
    printf("b = %d\\n", b);

    return 0;

calc.h:

#ifndef _CALC_H_
#define _CALC_H_

int add(int a, int b);
int sub(int a, int b);

#endif

calc.c:

#include "calc.h"

int add(int a, int b)

    return a + b;


int sub(int a, int b)

    return a - b;

编译:

arm-linux-gnueabihf-gcc main.c calc.c

交叉编译生成 a.out 可执行文件,文件类型是32位ARM平台可执行文件。

三、readelf工具

readelf工具由编译器提供,用来列出关于可执行文件的内容的相关信息

使用格式如下:

Usage: readelf <option(s)> elf-file(s)

(1)查看可执行文件的头部 信息

  • -h:用于列出ELF文件的头部信息,包括可执行文件运行的平台、软件版本、程序入口地址,以及program headers、section header等信息;


(2)查看section header

  • -S:用于列出程序中section的头部信息

四、可执行文件的组成结构

一个可执行文件由一系列section构成,section称为段,包括:代码段text、只读数据段rodata、数据段data、bss段等。

每个section用一个section header描述,包括段名、段的类型、段的起始地址、段的偏移、段的大小等。

将可执行文件的所有section header集合到一起就是section header table,使用readelf 的 -S 参数查看的就是该表。

在程序编译的时候,对C语言代码中定义的函数、变量、未初始化的全局变量进行编译分类,放置在不同的段中:

  • 普通代码翻译成二进制放到代码段(text)中
  • 常量放在只读数据段(rodata)中
  • 初始化的全局变量和静态局部变量放在数据段(data)中

BSS段比较特殊,未初始化的全局变量和静态变量都会放置到bss段中,但因为这些变量的值都是0,没有必要再开辟空间存储,所以在可执行文件中bss段是不占用空间的。

但是BSS段的大小、起始地址、各个变量的地址信息都会分别保存在section header table和符号表symtab中,当程序运行的时候,加载器会根据这些信息在内存中紧挨着数据段之后的空间,为BSS段开辟一片存储空间,为各个变量分配存储空间。

总而言之:BSS段在可执行文件中不占用空间,在程序运行的时候才分配对应的空间

如果在编译时开启了调试选项,则可执行文件中还会有 .debug section,用来保存可执行文件中每一条二进制指令对应的源码位置信息,根据这些信息,GDB调试器就可以支持源码级的单步调试。

在最后环节,编译器还会在可执行文件中添加一些其它的section,比如 .init section,这些代码来自C语言运行库的一些汇编代码,用来初始化C程序所依赖的环境。

参考资料

c语言程序是如何跑起来的(代码片段)

       有没有想过一个程序是如何运行的?平时点击运行,就直接出来了       那么它在点击运行到生成可执行程序这一期间到底经历了什么让我们一探究竟翻译       在翻译环境下会进行以下操作,预编... 查看详情

《程序是怎样跑起来的》第八章

...地代码,cpu直接解析并运行的不是源代码而是本地代码的程序。不同编程语言编写的代码,转换成本地代码后,都变成一种语言(机器语言)来表示了。2.本地代码的内容就是数值的罗列。计算机指令也是数值的罗列。3.编译后生成... 查看详情

终端里面的程序是怎样跑起来的

  比如mac环境下在某个路径下面跑celery的任务,celery-Amsg_taskworker 对于这一段语句的理解其实就是用后面的这些参数跑起来celery的可执行文件;那具体是怎样跑起来的呢,分为如下的四个步骤。一:mac的环境变量  mac一... 查看详情

读《程序是怎么跑起来的》第一章有感

...和时钟四个部分构成,各部分之间由电流信号相互连通。程序是把寄存器作为对象来描述的。寄存器有许多不同的种类,与其种类相对应的是其不同的功能。程序的流程分为循序执行,条件分支和循环三种。cpu的执行比较是由cpu... 查看详情

如何写个bat文件跑java程序

如何写个bat文件跑java程序感谢记事本新建一个文本文件,保存为*.bat如果为可执行jar,比如名字叫aa.jar,文本内容如下:java-jaraa.jar如果是普通的一个编译通过的类,比如名字叫aa.class,则文本内容:javaaa保存文本文件,双击。参考... 查看详情

《程序是怎样跑起来的》第一章

...数据和运算后的数据,栈寄存器存储栈区域的起始地址在程序的流程也分为三种顺序执行,条件分支和循环,读完后收获很大。 查看详情

《程序是怎样跑起来的》第八章读后感

...件,负责实现该功能的是编译器。用某种编程语言编写的程序就称为源代码,编译器负责转换源代码。   程序加载时会生成栈和堆,栈是用来存储函数内部临时使用的变量,以及函数调用时所用的参数的内存区域,堆... 查看详情

c代码是如何跑起来的(代码片段)

...U上面跑起来的。C语言提供了什么C语言作为高级语言,为程序员提供了更友好的表达方式。在我看来,主要是提供了以下抽象能力:变量,以及延伸出来的复杂结构体我们可以基于变量来描述复杂的状态。函数我们可以基于函数... 查看详情

《程序是怎么跑起来的》第七章

运行环境=操作系统+硬件。操作系统和硬件决定了程序的运行环境,同一类型的硬件可以选择安装多种操作系统。从程序的运行环境这一角度来考量硬件时,CPU的种类是特别重要的参数。CPU只能解释其自身固有的机器语言,不同... 查看详情

《程序是怎样跑起来的》第一章读后感

...能够直接解释和执行的语言。汇编,是将汇编语言编写的程序转换成机器语言的过程。反汇编,是机器语言程序转化为汇编语言程序的过程。3.寄存器有很多种类。例如:累加寄存器,标志寄存器,程序计数器,基址寄存器,变址... 查看详情

如何在 C# 中获取当前可执行文件的名称?

...:2009-03-0521:00:07【问题描述】:我想获取当前正在运行的程序的名称,即程序的可执行名称。在C/C++中,您可以从args[0]获得它。【问题讨论】:可执行文件是EXE文件(Windows窗体、WPF应用程序)?程序可以是桌面应用程序(WinForms... 查看详情

《程序是怎样跑起来的》第五章有感

 存储部件内存和磁盘从都具有存储程序命令和数据这点来看的功能是相同的。从存储容量来看,内存是高速高价,而磁盘是低速低价。内存主要是指主内存(负责存储CPU中运行的程序指令和数据的内存)磁盘主要是指硬盘。... 查看详情

目标代码文件可执行文件和库

   C程序的执行过程可分为:编辑、编译、连接、运行。   将程序源代码转换为可执行文件,需要编译与连接这两个步骤。编译器将源代码转换为中间代码,然后链接器将此中间代码与其他代码结合起来,... 查看详情

《程序是怎样跑起来的》第一章读后感

   读了《程序是怎样跑起来的》这本书的第一章之后,让我对CPU的理解更加深入。刚开始我只认为它是相当于计算机的大脑,原来它对于程序员来说不止如此,它还是CPU,寄存器,内存,内存地址,程序计数器,累计... 查看详情

《程序是怎样跑起来的》第一章有感

   在没有读《程序是怎样跑起来的》,这本书之前,我对于第一章所讲解CPU在脑子中只是知道它相当于是计算机的大脑,内部由数百万至数亿个晶体管构成。这本书在开始是就先对CPU的内部结构进行了解析,知道了CPU... 查看详情

《程序是怎样跑起来的》第一章读后感

...一章CPU,从学习计算机之初,我一直认为CPU和我们这些“程序员”无关,认为CPU只是计算机的组成部件。而我们学习语言,编写程序与打代码是在计算机上操作,所以从未考虑到CPU这个部件的作用。后来慢慢的,也通过《程序是... 查看详情

android上如何运行可执行文件(.exe格式)的

...买了一个联想乐PAD。需要工具:1、网上下载Bochs模拟器主程序(就是一个apk程序文件)2、配置文件(已经打包好在附件里)3、系统镜像操作步骤步骤1:安装模拟器主程序(这个就不用多说了,和普通安卓应用一样)步骤2:将... 查看详情

读《程序是怎么跑起来的》第8章

CPU可以解析和运行的程序形式是机器语言;将多个目标文件结合生成EXE文件的工具是链接器;扩展名为.obj的目标文件的内容是本地代码;把多个目标文件收录在一起的文件是库文件;仅包含Windows的DLL文件中存储的函数信息的文... 查看详情