模拟嵌入式开发,编写一个“体积受限”的可执行程序,通过makefile 完成编译, 运行后打印“D.T.Software”
传统的写法:test.c
#include <stdio.h>
void main()
{
print("D.T.Software\n");
return 0;
}
今天我们采用全新的方法,达到体积最小的 目标。
1.通过内嵌汇编自定义打印函数和退出函数(INT 80H)
2.通过链接脚本自定入口函数(不依赖任何库和gcc内置功能)
3.删除可执行程序中的无用信息(无用段信息、调试信息、等)
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"
);
}
ENTRY(program)
SECTIONS
{
.text 0x08048000 + SIZEOF_HEADERS :
{
*(.text)
*(.rodata)
}
/DISCARD/ :
{
*(*)
}
}
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 $@ $<
@echo "Target File ==> $@"
$(OBJ) : $(SRC)
$(CC) -fno-builtin -o $@ -c $^
rebuild : clean all
all : $(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命令进一步去除无用调试信息:
对于资源受限的嵌入式设备,需要考虑可执行程序的大小,通过内嵌汇编直接使用系统服务能够劈开相关库的使用可以通过如下方法控制可执行程序的体积大小。
1.最小化库的使用(必要情况下考虑自己实现相关函数)
2.自定义链接脚本,删除无用段信息
文章整理参考自狄泰课程。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。