链接器下——链接器实战

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链接器下——链接器实战相关的知识,希望对你有一定的参考价值。

链接器实战

1目标

模拟嵌入式开发,编写一个“体积受限”的可执行程序,通过makefile 完成编译, 运行后打印“Hello BT”

2分析过程

技术分享图片

3解决方案

1.通过内嵌汇编自定义打印函数和退出函数(INT 80H)
2.通过链接脚本自定入口函数(不依赖任何库和gcc内置功能)
3.删除可执行程序中的无用信息(无用段信息、调试信息、等)

4打印函数设计

void print(const char* s, int l)
{
    asm volatile (
        "movl $4, %%eax\n"
        "movl $1, %%ebx\n"
        "movl %0, %%ecx\n"
        "movl %1, %%edx\n"
        "int $0x80     \n"
        :
        : "r"(s), "r"(l)
        : "eax", "ebx", "ecx", "edx"
    );
}

5退出函数设计

void exit(int code)
{
    asm volatile (
        "movl $1, %%eax\n"
        "movl %0, %%ebx\n"
        "int $0x80     \n"
        :
        : "r"(code)
        : "eax", "ebx"
    );
}

6链接脚本设计

ENTRY(program)

SECTIONS
{
    .text 0x08048000 + SIZEOF_HEADERS :
    {
        *(.text)
        *(.rodata)
    }

    /DISCARD/ :
    {
        *(*)
    }
}

7 makefie

CC := gcc
LD := ld
RM := rm -fr

TARGET := program.out
SRC := $(TARGET:.out=.c)
OBJ := $(TARGET:.out=.o)
LDS := $(TARGET:.out=.lds)

.PHONY : rebuild clean all

$(TARGET) : $(OBJ) $(LDS)
    $(LD) -static -T $(LDS) -o [email protected] $<
    @echo "Target File ==> [email protected]"

$(OBJ) : $(SRC)
    $(CC) -fno-builtin -o [email protected] -c $^

rebuild : clean all

all : $(TARGET)

clean :
    $(RM) $(TARGET) $(OBJ)

8指定链接选项

  • -ld 命令 // GNU的链接器,将目标文件链接为可执行程序,GCC编译器集成中的一员,重要的幕后工作者
  • -ld -static // 指定使用静态链接的方式来产生最终程序,而不是默认的动态链接方式。
  • -gcc -fno-builtin //用于关闭GCC 内置函数的功能(GCC提供了很多内置函数(Built-in Function),它会将一些常用的C库函数替换为编译器的内置函数,以达到优化的目的)。

    9总结

    对于资源受限的嵌入式设备,需要考虑可执行程序的大小,通过内嵌汇编直接使用系统服务能够劈开相关库的使用可以通过如下方法控制可执行程序的体积大小。
    1.最小化库的使用(必要情况下考虑自己实现相关函数)
    2.自定义链接脚本,删除无用段信息

以上是关于链接器下——链接器实战的主要内容,如果未能解决你的问题,请参考以下文章

学习笔记 链接

链接器链接过程及相关概念解析

损坏的顶点和片段着色器

如何缩短 Visual Studio 中的链接过程

微信小程序代码片段

链接问题 C++、glew 和 SDL