1. 问题:Linux如何执行main函数。

本文使用一个简单的C程序(simple.c)作为例子讲解。代码如下,

  1. int main()
  2. {
  3. return(0);
  4. }

2.  编译

~#gcc -o simple simple.c

3. 查看可执行文件的基本信息

~#objdump -f simple

simple: file format elf32-i386 architecture: i386, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address 0x080482d0

借助objdump这个工具,可以获得可执行文件的一些关键信息。

比如,simple文件的格式是“ELF32”,该文件的起始地址是0x80482d0,,等。

4. 什么是ELF

ELF是Executable and Linking Format的缩写,是Unix上常见的几种目标文件格式(及可执行文件格式)之一。

ELF的头部结构提供了ELF文件的基本信息,其数据结构可以在/usr/include/elf.h 中看到,如下所示:

  1. typedef struct
  2. {
  3. unsigned char   e_ident[EI_NIDENT]; /* Magic number and other info */
  4. Elf32_Half  e_type;         /* Object file type */
  5. Elf32_Half  e_machine;      /* Architecture */
  6. Elf32_Word  e_version;      /* Object file version */
  7. Elf32_Addr  e_entry;        /* Entry point virtual address */
  8. Elf32_Off   e_phoff;        /* Program header table file offset */
  9. Elf32_Off   e_shoff;        /* Section header table file offset */
  10. Elf32_Word  e_flags;        /* Processor-specific flags */
  11. Elf32_Half  e_ehsize;       /* ELF header size in bytes */
  12. Elf32_Half  e_phentsize;        /* Program header table entry size */
  13. Elf32_Half  e_phnum;        /* Program header table entry count */
  14. Elf32_Half  e_shentsize;        /* Section header table entry size */
  15. Elf32_Half  e_shnum;        /* Section header table entry count */
  16. Elf32_Half  e_shstrndx;     /* Section header string table index */
  17. } Elf32_Ehdr;

其中,e_entry存储了该执行文件的起始地址。

5. 关于起始地址

~#objdump -d simple

  1. 80482d0 <_start>:
  2. 80482d0:       31 ed                   xor    %ebp,%ebp
  3. 80482d2:       5e                      pop    %esi
  4. 80482d3:       89 e1                   mov    %esp,%ecx
  5. 80482d5:       83 e4 f0                and    $0xfffffff0,%esp
  6. 80482d8:       50                      push   %eax
  7. 80482d9:       54                      push   %esp
  8. 80482da:       52                      push   %edx
  9. 80482db:       68 20 84 04 08          push   $0x8048420
  10. 80482e0:       68 74 82 04 08          push   $0x8048274
  11. 80482e5:       51                      push   %ecx
  12. 80482e6:       56                      push   %esi
  13. 80482e7:       68 d0 83 04 08          push   $0x80483d0
  14. 80482ec:       e8 cb ff ff ff          call   80482bc <_init+0x48>
  15. 80482f1:       f4                      hlt
  16. 80482f2:       89 f6                   mov    %esi,%esi

该命令可以得到simple的反汇编代码,可以看到,起始地址0x80482d0对应的是_start这个routine。这段代码所做的事情是,将ebp清0,调整esp的值,然后将一些数据压栈,最后调用一个函数。

Linux中Main函数的执行过程的更多相关文章

  1. Linux中main是如何执行的

    Linux中main是如何执行的 这是一个看似简单的问题,但是要从Linux底层一点点研究问题比较多.找到了一遍研究这个问题的文章,但可能比较老了,还是在x86机器上进行的测试. 原文链接 开始 问题 ...

  2. Linux系统中,main函数的执行过程

    http://blog.csdn.net/rrerre/article/details/6728431

  3. 多玩YY语音的面试题:C++中如何在main()函数之前执行操作?

    多玩YY语音的面试题:C++中如何在main()函数之前执行操作? 第一反应main()函数是所有函数执行的开始.但是问题是main()函数执行之前如何执行呢? 联想到MFC里面的 C**App类的t ...

  4. 【转】linux 中fork()函数详解

    在看多线程的时候看到了这个函数,于是学习了下,下面文章写的通俗易懂,于是就开心的看完了,最后还是很愉快的算出了他最后一个问题. linux 中fork()函数详解 一.fork入门知识 一个进程,包括 ...

  5. 全局对象的构造函数会在main函数之前执行?

    #include <iostream> using namespace std; class CTest { public: CTest() { cout << "构 ...

  6. atexit注册的函数是在main函数之后执行?

    跟atexit函数相识已久,man手册里对atexit的解释是这么一段: The atexit() function registers the given function to be called ...

  7. 在C++工程中main函数之前跑代码的廉价方法(使用全局变量和全局函数)

    // test.cpp : Defines the entry point for the console application. // #include "stdafx.h" ...

  8. linux中 probe函数的何时调用的?

    点击打开链接 linux中 probe函数何时调用的 所以的驱动教程上都说:只有设备和驱动的名字匹配,BUS就会调用驱动的probe函数,但是有时我们要看看probe函数里面到底做了什么,还有传递给p ...

  9. Linux中的定时自动执行功能(at,crontab)

    Linux中的定时自动执行功能(at,crontab) 概念 在Linux系统中,提供了两种提前对工作进行安排的方式 at 只执行一次 crontab 周期性重复执行 通过对这两个工具的应用可以让我们 ...

随机推荐

  1. 如何解决前端传来的时间格式与mysql表中时间格式不匹配的查询问题

    前端传过来的时间格式为“2016-07-11 11:13:10”,而数据表中对应字段`add_time`的格式为“2016-7-11”,此时sql不能直接用 "where `add_time ...

  2. alert弹层无法取消问题解决办法

    最近做H5移动端开发的时候,js代码写了个alert,在Android手机上能正常运行,但是在IOS上运行弹出之后却无法取消掉, 而且页面卡死,点不了任何东西,这种情况是非常不好的,用户体验非常糟糕. ...

  3. 抽象工厂模式(Abstract Factory Pattern)

    动机(Motivation) 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作:同时,由于需求的变化,往往存在更多系列对象的创建工作.如何应对这种变化?如何绕过常规的对象创建方法(new), ...

  4. 学习中的错误——ubuntu 14.04 LTS 启动eclipse报错

    在ubuntu中启动eclipse报错:(Eclipse:15978): GLib-GIO-CRITICAL **: g_dbus_connection_get_unique_name: assert ...

  5. FB

    转眼间,开始工作到现在好几年,忙着功能,忙着补漏填坑,忙着项目,现在回顾着开始的理想,一时有点恍惚,然后鄙视了下自己居然还在“理想”中…… 那就开始吧,做点什么呢? DX9/DX11的支持是必须的,S ...

  6. atexit函数

    使用该函数注册的退出函数是在进程正常退出时,才会被调用.这里强调是进程正常退出,使用exit退出或使用main中最后的return语句退出.但如果是因为收到信号signal而导致程序退出,如kill ...

  7. android activity改变另一个activity ui

    android开发之在activity中控制另一个activity的UI更新   转自:http://www.cnblogs.com/ycxyyzw/p/3875544.html 第一种方法: 遇到一 ...

  8. C#读取大文本文件

    今天偶遇一同事抱怨,sqlserver导出的CSV,明明有1000W条,但用excel打开就只剩100W了,足足消失了90%,所以她怀疑文件是足量的1000W条,是excel捣了鬼.可是文件容量有2G ...

  9. 《Linux内核分析》实验一

    陈智威,<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 课堂学习笔记: 作业截图: 汇编代码堆栈分析: ...

  10. nexus7 二代 升级 android L

    折腾了半天 ,最后发现其实很简单... 1.装好windows下gdb和bootloader的驱动,注意打开usb debug,另外进入bootloader是开机按电源键和音量减小键,至于要解锁这个想 ...