Originally Posted by
Dino
In the #define solution above, will the, for instance, B500 fields, since not directly used, be part of the executable, affecting the final size of the executable?
But they are directly used! And, yes, using a literal can increase the executable size. but not always. As an example, these two functions are the same in my machine, using GCC 10.2):
Code:
#include <stdio.h>
#include <string.h>
#define B10 " "
#define B50 B10 B10 B10 B10 B10
#define B100 B50 B50
#define STRSIZE 100
void f( void )
{
char s[STRSIZE+1] = B100;
puts( s );
}
void g( void )
{
char s[STRSIZE+1];
memset( s, ' ', sizeof s - 1 );
s[sizeof s - 1] = '\0';
puts( s );
}
Both create the same asm code with maximum optimization:
Code:
$ cc -O2 -fomit-frame-pointer -fcf-protection=none -fno-stack-protector -c -o test.o test.c
Code:
section .text
f: ; and g:
; Reserve space for s.
sub rsp, 120
; Fill the array s.
movdqa xmm0, [spaces]
mov rdi, rsp
mov DWORD [rsp+96], 0x20202020
mov BYTE [rsp+100], 0
movups [rsp], xmm0
movups [rsp+16], xmm0
movups [rsp+32], xmm0
movups [rsp+48], xmm0
movups [rsp+64], xmm0
movups [rsp+80], xmm0
call puts wrt ..plt
; Dispose of s.
add rsp, 120
ret
section .rodata
align 16
spaces:
times 2 dq 0x2020202020202020
In other cases, like this:
Code:
#include <stdio.h>
#include <string.h>
#define STRSIZE 79
#ifdef STATIC
void f( void )
{
char s[STRSIZE+1] = "abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz";
puts( s );
}
#else
void f( void )
{
char s[STRSIZE+1];
char *p;
s[sizeof s - 1] = '\0';
p = s;
for ( int j = 0; j < 3; j++ )
for ( int i = 'a'; i <= 'z'; i++ )
*p++ = i;
puts( s );
}
#endif
We have:
Code:
$ cc -DSTATIC -O2 -fomit-frame-pointer -fcf-protection=none -fno-stack-protector -c -o test1.o test.c
$ cc -O2 -fomit-frame-pointer -fcf-protection=none -fno-stack-protector -c -o test2.o test.c
$ objdump -x test1.o | sed -n '/^Sec/,/^SYM/p'
Sections:
Idx Name Siz. VMA LMA File off Algn
0 .text 00000051 0000000000000000 0000000000000000 00000040 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 0000000000000000 0000000000000000 00000091 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 0000000000000000 0000000000000000 00000091 2**0
ALLOC
3 .rodata.cst16 00000050 0000000000000000 0000000000000000 000000a0 2**4
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .comment 00000028 0000000000000000 0000000000000000 000000f0 2**0
CONTENTS, READONLY
5 .note.GNU-stack 00000000 0000000000000000 0000000000000000 00000118 2**0
CONTENTS, READONLY
6 .eh_frame 00000030 0000000000000000 0000000000000000 00000118 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
SYMBOL TABLE:
$ objdump -x test2.o | sed -n '/^Sec/,/^SYM/p'
Sections:
Idx Name Siz. VMA LMA File off Algn
0 .text 00000049 0000000000000000 0000000000000000 00000040 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 0000000000000000 0000000000000000 00000089 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 0000000000000000 0000000000000000 00000089 2**0
ALLOC
3 .comment 00000028 0000000000000000 0000000000000000 00000089 2**0
CONTENTS, READONLY
4 .note.GNU-stack 00000000 0000000000000000 0000000000000000 000000b1 2**0
CONTENTS, READONLY
5 .eh_frame 00000030 0000000000000000 0000000000000000 000000b8 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
SYMBOL TABLE:
Notice the extra .rodata section with 80 bytes (values in hexadecimal) on test1.o.
[]s
Fred