Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Application of Linker (8)

2025-01-21 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/03 Report--

In the previous blog, we introduced the concepts of linkers. So in this section, we will continue to look at the linker and see its application in engineering practice. We do an experiment in this section to simulate embedded development.

The goal of the experiment:

1. Write a "volume-limited" executable program

2. Complete the code compilation through makefile

3. Print "D.T.Software" on the screen after running

So the goal seems simple: we print the classic hello world directly when we are beginners to program. The effect is similar, and the classic code is

# include int main () {printf ("D.T.Software"); return 0;}

Of course, this code also works, but our requirement is that the size is limited. What is volume restriction? As we all know, in embedded development, memory is very small. So saving memory is an essential factor, so we have to drop some additional information contained in the library file and keep only the code needed to print the statement. So let's take an in-depth analysis of how to develop it. There is no doubt that it is written directly in assembly code, and then write a link script to customize the entry address. The idea is as follows

As we can see from the above, our solution can be completed by the following parts:

1. Customize the print function and exit function through embedded assembly (INT 80H)

2. Customize the entry function through the link script (does not depend on any libraries and GCC built-in functions)

3. Delete the useless information (useless segment information, debugging information, etc.) in the executable program.

The print function is designed as follows

Void print (const char* s, int l) {asm volatile ("movl $4,% eax\ n" / / sysy_write "movl $1,% ebx\ n"movl% 0,% ecx\ n"movl% 1,% edx\ n"int $0x80\ n" / / 80H Service:: "r" (s) "r" (1) / parameter: "eax", "ebx", "ecx", "edx") }

The exit function is designed as follows

Void exit (int code) {asm volatile ("movl $1,% eax\ n" / / sys_exit "movl% 0,% ebx\ n"int $0x80\ n" / / 80H Service:: "r" (code) / / parameter: "eax", "ebx");}

The link script is designed as follows

ENTRY (program) / / specify the entry function SECTIONS {.text 0x08048000 + SIZEOF_HEADRS: {* (.text) / / merge the two segments in the target file into the executable program * (.rodata)} / DISCARD/: {* (*) / discard all segments in the object file except .test and .rodata}}

Finally, here are a few commands:

1. Ld command: a linker for GNU that links the target file as an executable program; a member of the GCC compiler set.

2. Ld-static: indicates that ld uses static linking to generate the final program, rather than the default dynamic linking.

3. Gcc-fno-builtion: used to turn off the function of the built-in function in GCC.

In GCC, it provides many built-in functions (Built-in Function), and the-fno-builtion option replaces some commonly used C library functions with compiler built-in functions for optimization purposes.

Program.c source code

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" / / call the system write function with the number 4 "movl $1,% ebx\ n" / / specify the parameter and print the string to the screen "movl% 0,% ecx\ n" / / placeholder Represents the first parameter (address) "movl% 1,% edx\ n"int $0x80\ n" / / interrupt: / / input parameter is empty: "r" (s), "r" (l) / / pass the parameter: "eax" in read-only form "ebx", "ecx", "edx" / / initialization register) } void exit (int code) {asm volatile ("movl $1,% eax\ n"movl% 0,% ebx\ n"int $0x80\ n": "r" (code): "eax", "ebx");}

Makefile is written as follows

CC: = gccLD: = ldRM: = rm-rfTARGET: = 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)

Let's run it and see how it turns out.

The result is exactly what we want, so what is the point of going to so much trouble to write such complex code? Let's take a look at its memory size, and the code to write a normal printf print statement, and compare the memory size of the two executable files.

We can see that the effect is the same, but the difference between normal printf printing and the function writing of our custom link script is more than ten times the memory required. In other words, in embedded development, resources are very valuable this practice is necessary. Through today's example analysis of the linked script, it is summarized as follows: 1. For resource-constrained embedded devices, the file size of the executable program needs to be considered; 2. The direct use of system services through embedded assembly can avoid the use of related libraries; 3. The size of the executable program can be controlled by the following methods: a > minimize the use of libraries (implement related functions by yourself if necessary) B > customize the link script to delete the useless segment information.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report