저는 환경과 같은 임베디드 OS로 작업하고 있으므로 바이너리의 크기는 가능한 한 작아야합니다. 나는 실행 파일로 간단한 플랫 바이너리 파일을 사용하고 있었지만 지금은 ELF를 사용하려고한다. 난 그냥 어셈블리 코드를 사용하고 있지만 ld와 링크하고있다. 어셈블리 코드 :왜이 간단한 어셈블리 코드를 컴파일하고 ELF에 링크하면 플랫 바이너리보다 더 큰 크기가됩니까?
CPU i386
BITS 32
SECTION .text progbits alloc exec nowrite
GLOBAL start
start:
mov eax, 0
add eax, 1
inc eax
mov eax, 0x12345678
mov dword [0x100000], eax
mov ebx, dword [0x100000]
mov eax, ebx
out 0xF3, al ;dump memory API call
out 0xF0, ax
cli
hlt
빌드 명령 :
yasm -o testbench/test.o testbench/test.asm -f elf32
i386-elf-gcc -T testbench/linker.ld -o test.elf -ffreestanding -nostdlib testbench/test.o -Wl,--gc-sections -dead_strip -fdata-sections -ffunction-sections -Os -nostartfiles -nodefaultlibs
strip --strip-all test.elf
그리고 마지막으로, 링커 스크립트 :
이 readelf 목록에 결과OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
phys = 0x1000;
scratch = 0x100000;
MEMORY
{
coderom (rx) : ORIGIN = phys, LENGTH = 128K
scratchram (!rx) : ORIGIN = scratch, LENGTH = 1024K
}
SECTIONS
{
.text phys : AT(phys) {
code = .;
*(.text.start);
*(.text*)
*(.rodata)
. = ALIGN(4);
} > coderom
__text_end=.;
.data : AT(scratch)
{
data = .;
*(.data)
. = ALIGN(4);
} > scratchram
__data_end=.;
__binary_end = .;
.bss : AT(scratch + (bss - data))
{
bss = .;
*(.bss)
. = ALIGN(4);
} > scratchram
}
:
[email protected]:~/x86LibSC$ readelf -a test.elf
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
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x1000
Start of program headers: 52 (bytes into file)
Start of section headers: 4160 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 5
Section header string table index: 4
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 00001000 001000 000024 00 AX 0 0 16
[ 2] .data PROGBITS 00100000 001024 000000 00 WA 0 0 1
[ 3] .bss NOBITS 00100000 000000 000000 00 WA 0 0 1
[ 4] .shstrtab STRTAB 00000000 001024 00001c 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x001000 0x00001000 0x00001000 0x00024 0x00024 R E 0x1000
Section to Segment mapping:
Segment Sections...
00 .text
There is no dynamic section in this file.
There are no relocations in this file.
The decoding of unwind sections for machine type Intel 80386 is not currently supported.
No version information found in this file.
당신이 할 수 이걸 컴파일해야한다. 최대 또는 100 바이트 또는 200 바이트 (플랫 바이너리 형식을 사용하는 경우). 그러나 어떤 이유로이 크기는 4KB를 초과합니다.
어셈블러에서 수동으로 ELF 파일을 빌드하는 것이 가능한 한 ELF 프로그램 크기를 가능한 줄이려면 어떻게합니까?
참고로이 OS 환경에서는 재배치 또는 동적 코드가 없습니다. 그냥 플랫 프로그램 섹션을로드합니다.
'.text' 정렬이 4k로 설정되어있는 것처럼 보입니다. – Jester
프로그램 헤더 비트에 대해 파일 자체에서 4K로 정렬되어 있음을 알았지 만 LD에 @Jester를하지 말라고 말하지 않습니다. – Earlz
4kb 정렬은 잠재적으로 입력 섹션에서 발생합니다. 오브젝트 파일을 처리하고 최종 실행 파일의 출력 섹션으로 전달합니다. '.text'와'.data' 라인에서 SUBALIGN 지시어를 사용하여이를 검증 할 수 있습니다. 그래서 이것은'.text phys : AT (phys) SUBALIGN (64)'와'.data : AT (scratch) SUBALIGN (64)'64를 사용할 수 있습니다. 잘). –