`
tcspecial
  • 浏览: 911603 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

最小helloworld

    博客分类:
  • OS
阅读更多

hello world程序是学每种编程语言的启蒙程序,所谓麻雀虽小,五脏俱全。最近看《程序员的自我修养》最小helloworld程序章节,觉得甚是精彩,特此整理下。

 

一. 入门级helloworld

[root@dev21 elf]# ll tinyhello
-rwxr-xr-x  1 root root 4719 Dec  9 14:31 tinyhello

[root@dev21 elf]# readelf -h tinyhello
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Number of program headers:         7
  Size of section headers:           40 (bytes)
  Number of section headers:         28
  Section header string table index: 25

 

上述代码调用printf()函数打印字符串,程序调用了glib库,编译文件大小为4.7k。glibc库太庞大,编译出的程序包含很多段,有28个段。

 

二. 汇编优化

char *str = "Hello world!\n";

/**
 * 调用中断服务write(),eax传递中断号4,ebx,ecx,edx传递参数
 * 中断服务表见:linux-3.18.6/arch/x86/syscalls/syscall_32.tbl
 */
void print()
{
	asm( "movl $13,%%edx \n\t"
	    "movl %0,%%ecx \n\t"
	    "movl $0,%%ebx \n\t"
	    "movl $4,%%eax \n\t"
	    "int $0x80 	   \n\t"
	    ::"r"(str):"edx","ecx","ebx" );
}

// 中断调用exit()
void exit()
{
	asm( "movl $42,%ebx \n\t"
	     "movl $1,%eax  \n\t"
	     "int $0x80	    \n\t" );
}

// 系统入口
void nomain()
{
	print();
	exit();
}

 

由于没有使用main函数,无法直接编译,需手动指定函数入口nomain。

gcc -c -fno-builtin tinyhello.c
ld -static -e nomain -o tinyhello tinyhello.c

  

[root@dev21 elf]# ll tinyhello1
-rwxr-xr-x  1 root root 1031 Dec  9 16:01 tinyhello1
[root@dev21 elf]# readelf -h tinyhello1
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Number of program headers:         3
  Size of section headers:           40 (bytes)
  Number of section headers:         9
  Section header string table index: 6

[root@dev21 elf]# readelf -S tinyhello1
There are 9 section headers, starting at offset 0x154:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        08048094 000094 00003f 00  AX  0   0  4
  [ 2] .rodata           PROGBITS        080480d3 0000d3 00000e 00   A  0   0  1
  [ 3] .data             PROGBITS        080490e4 0000e4 000004 00  WA  0   0  4
  [ 4] .bss              NOBITS          080490e8 0000e8 000000 00  WA  0   0  4
  [ 5] .comment          PROGBITS        00000000 0000e8 00002e 00      0   0  1
  [ 6] .shstrtab         STRTAB          00000000 000116 00003d 00      0   0  1
  [ 7] .symtab           SYMTAB          00000000 0002bc 000110 10      8  10  4
  [ 8] .strtab           STRTAB          00000000 0003cc 00003b 00      0   0  1

 

C语言嵌套汇编版本的hello world才1k左右,含9个段。

 

三. 合并程序段

程序2中存在.text,.rodata,.data三个段,可以整合到一个段中,通过链接脚本实现。

 

ENTRY(nomain)

SECTIONS
{
	. = 0x08048000 + SIZEOF_HEADERS;
	tinytext : {*(.text) *(.data) *(.rodata) }
	/DISCARD/ : { *(.comment) }
}

 

[root@dev21 elf]# gcc -c -fno-builtin tinyhello.c
[root@dev21 elf]# ld -static -T tinyhello.lds -o tinyhello2 tinyhello.o

[root@dev21 elf]# ll tinyhello2
-rwxr-xr-x  1 root root 795 Dec  9 16:34 tinyhello2

[root@dev21 elf]# readelf -S tinyhello2
There are 7 section headers, starting at offset 0x120:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] tinytext          PROGBITS        08048094 000094 000052 00 WAX  0   0  4
  [ 2] .bss              NOBITS          080480e8 0000e6 000000 00  WA  0   0  4
  [ 3] .note.GNU-stack   PROGBITS        00000000 0000e6 000000 00      0   0  1
  [ 4] .shstrtab         STRTAB          00000000 0000e6 000039 00      0   0  1
  [ 5] .symtab           SYMTAB          00000000 000238 0000c0 10      6   8  4
  [ 6] .strtab           STRTAB          00000000 0002f8 000023 00      0   0  1

 

 编译后的程序只有795B,减少了300多字节。

 

四. 移除符号表

程序3含有.symtab,.strtab两个段,可以通过strip命令移除。

 

[root@dev21 elf]# strip tinyhello3

[root@dev21 elf]# ll tinyhello3
-rwxr-xr-x  1 root root 472 Dec  9 16:39 tinyhello3

[root@dev21 elf]# readelf -S tinyhello3
There are 5 section headers, starting at offset 0x110:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] tinytext          PROGBITS        08048094 000094 000052 00 WAX  0   0  4
  [ 2] .bss              NOBITS          080480e8 0000e6 000000 00  WA  0   0  4
  [ 3] .note.GNU-stack   PROGBITS        00000000 0000e6 000000 00      0   0  1
  [ 4] .shstrtab         STRTAB          00000000 0000e6 000029 00      0   0  1

 

最终程序只有472个字节。

 

 参考资料:《程序员的自我修养》

  

 

分享到:
评论

相关推荐

    最小的C语言Helloworld程序

    "最小的C语言Hello, world程序"是每个初学者接触C语言时的第一个示例,它展示了如何用最少的代码实现一个简单的输出功能。 这个最小的C语言程序通常只包含以下几行代码: ```c #include int main() { printf(...

    cpp-HelloWorld执行的最小指令集和汇编器编译器

    这里我们将深入探讨"Hello World"程序在C++中的最小指令集、汇编器和编译器的工作原理。 1. **最小指令集**: 指令集是指计算机硬件系统中处理器能理解和执行的基本操作命令。在"Hello World"程序的执行过程中,...

    mybatis的Helloworld

    【标题】"mybatis的Helloworld" 在Java开发领域,MyBatis是一个广泛使用的持久层框架,它简化了数据库操作,使开发者能够更方便地进行数据存取。本篇文章将详细解析MyBatis的“Hello World”实例,帮助初学者快速...

    C语言蛋疼的Hello World代码

    ### C语言蛋疼的Hello World代码 #### 标题解析 标题中提到的“蛋疼的Hello World代码”暗示了这是一段非常规且复杂的实现方式,通常用于学习C语言中的指针、内存操作等高级概念。 #### 描述解析 描述部分展示了一...

    Android开发入门 实例 helloworld

    在Android开发领域,"Hello, World!"项目是一个经典的起点,它为初学者提供了一个简单而直接的编程体验,帮助他们理解和熟悉Android应用的基本构建过程。本文将深入探讨这个入门实例,带您逐步走进Android开发的世界...

    helloworld demo

    在移动开发领域,"HelloWorld" demo 是一个非常基础且重要的起点,尤其对于初次接触Android平台的开发者来说。这个简单的程序通常包含一个显示 "Hello, World!" 文本的界面,它是学习新编程语言或框架的第一步,因为...

    helloworld-nodejs:最小的NodeJS示例

    docker run --rm --name hello cogsmith/helloworld-nodejs # HELLOWORLD: 695144B4BC64 @ 2021-02-18T01:19:03.199Z 本地Web服务器@端口99 docker run -d --rm --name hellolocal --env PORT=9 -p 127.0.0.1:99:9 ...

    Vue预习课2:Hello World 第一个程序

    本课程的核心是通过“Hello World”实例来引导初学者理解Vue的基本概念和设计思想。 首先,让我们从“Hello World”程序开始。这是每个开发者学习新语言或框架时的入门步骤。在Vue中,创建“Hello World”程序非常...

    Hello world -- OS

    标题 "Hello world -- OS" 暗示我们正在探讨的是操作系统开发的基础教程,通常这个简单的程序是编程初学者进入系统编程领域的第一步。在这个场景中,"Hello world" 不再是简单的用户界面输出,而是可能涉及操作系统...

    struts2 HelloWorld最小必备包

    这个"struts2 HelloWorld最小必备包"是初学者入门Struts2框架的起点,它包含了运行一个简单的"Hello, World!"示例所需的所有核心组件。 1. **Struts2 Core** (`struts2-core-2.5.2.jar`): 这是Struts2框架的核心...

    VS2015下使用纯WIN32 API写的Hello World代码及程序!(C/C++最小版本)

    在本文中,我们将深入探讨如何在Visual Studio 2015环境下使用纯Windows API编写一个基本的"Hello, World!"程序。Windows API是Microsoft提供的一组函数和结构,用于开发Windows操作系统上的应用程序。这个API提供了...

    asm.zip_asm hello world_world

    标题 "asm.zip_asm hello world_world" 和描述 "asm hello world test" 暗示了这个压缩包的内容与汇编语言编程有关,特别是涉及到一个简单的 "hello world" 程序的创建和测试。汇编语言是计算机编程的一种底层语言,...

    工作流Hello World

    "helloWorld"这个文件可能是这个工作流示例的源代码或者配置文件。在许多工作流引擎中,如Activiti、Nintex、BPMN(Business Process Model and Notation)等,开发者通常会创建一个简单的“Hello World”流程来展示...

    Jbpm4HelloWorld

    【Jbpm4HelloWorld】是基于JBPM(Java Business Process Management)框架的入门示例,这个项目旨在帮助初学者快速理解并掌握JBPM的基本用法。JBPM是一个开源的工作流管理系统,它允许开发者设计、执行和管理业务...

    HelloWorld

    在创建新项目的过程中,你需要设置项目的基本信息,如项目名称(可以是"HelloWorld")、包名(通常以反向域名的形式表示,如com.example.helloworld)、最小SDK版本(决定应用支持的Android系统版本)等。...

    node-helloworld-docker:节点Helloworld的Docker映像

    什么是Node Helloworld? 这是一个用NodeJS编写的最小的hello world应用程序,用于测试目的。 TL; DR Docker撰写 $ curl -LO ...

    terraform-lambda-example:AWS Lambda的Hello World示例

    这是部署由AWS Lambda函数支持的HTTP API的最小Hello World示例。 该功能用Go编写,并且使用Terraform自动化部署。 先决条件 Terraform and Go 安装和 。 在具有Homebrew的macOS上: $ brew install go terraform ...

    air for android hello world

    标题 "air for android hello world" 暗示我们即将探讨的是使用Adobe AIR技术在Android平台上构建一个基础的“Hello World”应用。Adobe AIR(Adobe Integrated Runtime)允许开发者使用Flash、Flex或HTML5来创建跨...

    maven-hello-world:简单,最小的Maven示例:hello world

    一个简单,最小的Maven示例:hello world 要在此git repo中创建文件,我们已经运行了mvn archetype:generate from mvn archetype:generate -DgroupId=...

Global site tag (gtag.js) - Google Analytics