博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
链接器下——链接器实战
阅读量:5903 次
发布时间:2019-06-19

本文共 2244 字,大约阅读时间需要 7 分钟。

链接器实战

1目标

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

传统的写法:test.c

#include 
void main(){ print("D.T.Software\n"); return 0;}

今天我们采用全新的方法,达到体积最小的 目标。

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 := gccLD := ldRM := rm -frTARGET := program.outSRC := $(TARGET:.out=.c)OBJ := $(TARGET:.out=.o)LDS := $(TARGET:.out=.lds).PHONY : rebuild clean all$(TARGET) : $(OBJ) $(LDS)    $(LD) -static -T $(LDS) -o $@ $<    @echo "Target File ==> $@"$(OBJ) : $(SRC)    $(CC) -fno-builtin -o $@ -c $^rebuild : clean allall : $(TARGET)clean :    $(RM) $(TARGET) $(OBJ)

最终的设计:

void print(const char* s, int l);void exit(int code);void program(){    print("D.T.Software\n", 13);    exit(0);}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"    );}void exit(int code){    asm volatile (        "movl $1, %%eax\n"        "movl %0, %%ebx\n"        "int $0x80     \n"        :        : "r"(code)        : "eax", "ebx"    );}

编译后结果对比:(没有对比就没有伤害)

链接器下——链接器实战
还可以使用strip命令进一步去除无用调试信息:
链接器下——链接器实战

8指定链接选项

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

    9总结

    对于资源受限的嵌入式设备,需要考虑可执行程序的大小,通过内嵌汇编直接使用系统服务能够劈开相关库的使用可以通过如下方法控制可执行程序的体积大小。

    1.最小化库的使用(必要情况下考虑自己实现相关函数)
    2.自定义链接脚本,删除无用段信息

文章整理参考自狄泰课程。

转载于:https://blog.51cto.com/11134889/2072461

你可能感兴趣的文章
RE·WORK 巅峰对话:深度学习将彻底改变医疗健康领域
查看>>
计算机网络物理层
查看>>
CUDA学习(九十三)
查看>>
Mysql如何使自增字段重新计算?
查看>>
使用Telnet测试基本POP3服务
查看>>
Flink SQL 功能解密系列 —— 维表 JOIN 与异步优化
查看>>
Codeforces Round #442 (Div. 2) A B
查看>>
封装一个日期时间选择器
查看>>
极值问题(acms)
查看>>
swift UI专项训练8 展示数据
查看>>
openstacks
查看>>
PHP5下单独编译php模块
查看>>
字体图标学习
查看>>
局域网网速变慢的故障细致分析
查看>>
oracle 远程tns配置
查看>>
7.1.3.3. Using the Rails console with ActionPack
查看>>
虚拟桌面带宽评估
查看>>
一起学shell(十一)之安全的shell脚本:起点
查看>>
Microsoft® Deployment Toolkit 2010之快速部署Windows 7
查看>>
vue中this.$router.push()传参简单说明
查看>>